{"id":169,"date":"2013-04-05T12:09:38","date_gmt":"2013-04-05T17:09:38","guid":{"rendered":"http:\/\/homepages.uc.edu\/~yaozo\/wordpress\/?p=169"},"modified":"2013-04-05T12:09:38","modified_gmt":"2013-04-05T17:09:38","slug":"how-to-write-your-own-functions-and-good-r-programing-techniques","status":"publish","type":"post","link":"https:\/\/zhuoyao.net\/index.php\/2013\/04\/05\/how-to-write-your-own-functions-and-good-r-programing-techniques\/","title":{"rendered":"How to write your own functions and good R programing techniques"},"content":{"rendered":"<ul>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#How_to_write_your_own_functions\">How to write your own functions and good R programing techniques<\/a>\n<ul>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Good_R_Programing_Techniques\">Good R Programing Techniques<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Writing_Functions\">Writing Functions<\/a>\n<ul>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#The_R_function_Statement\">The R function Statement<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Function_Return_Values\">Function Return Values<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Function_Arguments\">Function Arguments<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Useful_Functions_for_Use_in_Func\">Useful Functions for Use in Functions<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#R_Gotchas\">R Gotchas<\/a>\n<ul>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Environments\">Environments<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#T_and_F_vs_TRUE_and_FALSE\">T and F vs. TRUE and FALSE<\/a><\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Object_name_confusion\">Object name confusion<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/RClinicHelpfulRCode4#Basic_Intro_to_debugging_in_R\">Basic Intro to debugging in R<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2><a name=\"Good_R_Programing_Techniques\"><\/a>Good R Programing Techniques<\/h2>\n<p>R is quite different from regular programing languages in the way that it executes the code given to it. Due to R&#8217;s eccentricities in order to create functions that run faster and consume less memory there are several guide lines to keep in mind. All of the guide lines are optional however as datasets get bigger the more benefits will be gained by following them.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Don&#8217;t use recursion. Recursion and the way R executes code results in functions that run slower and consume massive amounts of memory.<\/li>\n<li>If you use a complex calculation that is constant often in a function consider assigning it to its own variable.\n<ul>\n<li>Before:\n<pre>w &lt;- log(x) + log(y) + 10\nv &lt;- log(x) + log(y) + 32<\/pre>\n<\/li>\n<li>After:\n<pre>t &lt;- log(x) + log(y)\nw &lt;- t + 10\nv &lt;- t + 32<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>If you are only using a variable once consider eliminating that variable.\n<ul>\n<li>Before:\n<pre>f &lt;- function(n = 125000) {\n  x &lt;- runif(n)\n  sum(x + 1)\n}<\/pre>\n<\/li>\n<li>After:\n<pre>f &lt;- function(n = 125000) {\n  sum(runif(n) + 1)\n}<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li>When temporary variables are needed, using the same name for ones of the same size that are not required simultaneously can avoid unneeded copying.\n<ul>\n<li>Before:\n<pre>g &lt;- function(n = 125000) {\n  tmp &lt;- runif(n)\n  tmp1 &lt;- 2 * tmp + tmp^2\n  tmp2 &lt;- tmp1 - trunc(tmp1)\n  mean(tmp2 &gt; 0.5)\n}<\/pre>\n<\/li>\n<li>After:\n<pre>g1 &lt;- function(n = 125000) {\n  tmp &lt;- runif(n)\n  tmp &lt;- 2 * tmp + tmp^2\n  tmp &lt;- tmp - trunc(tmp)\n  mean(tmp &lt; 0.5)\n}<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Try not to use loops.\n<ul>\n<li>In R loops are very slow. In this example 15 is added to a 100000 element vector.\n<pre>n &lt;- 100000\na &lt;- runif(n)\nd &lt;- vector(mode=typeof(a), n)\n\nsystem.time(a + 15, gcFirst=TRUE)\nsystem.time(lapply(a, function(x) x + 15), gcFirst=TRUE)\nsystem.time(sapply(a, function(x) x + 15), gcFirst=TRUE)\nsystem.time(for(i in seq(along.with=a)) d[i] &lt;- a[i] + 15, gcFirst=TRUE)<\/pre>\n<\/li>\n<li>Use Vectorized Arithmetic,\u00a0<code>sapply<\/code>\u00a0or\u00a0<code>lapply<\/code>\u00a0instead.\n<ul>\n<li>Before\n<pre>over.thresh &lt;- function(x, threshold) {\n  for (i in 1:length(x))\n    if (x[i] &lt; threshold)\n      x[i] &lt;- 0\n  x\n}<\/pre>\n<\/li>\n<li>After\n<pre>over.thresh2 &lt;- function(x, threshold) {\n  x[x &lt; threshold] &lt;- 0\n  x\n}<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>For operations on individual elements of a list use the\u00a0<code>apply<\/code>\u00a0function family, such as\u00a0<code>lapply<\/code>,\u00a0<code>tapply<\/code>, etc&#8230;<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Avoid looping over a named data set. If necessary save any names by\u00a0<code>tnames &lt;- names(x)<\/code>\u00a0and then remove them by\u00a0<code>names(x) &lt;- NULL<\/code>, perform the loop, then reassign the names by\u00a0<code>names(x) &lt;- tnames<\/code>.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Avoid growing data sets in a loop. Always create a data set of the desired size before entering the loop; this greatly improves memory allocation. If you don&#8217;t know the exact size over estimate it and the shorten the vector at the end of the loop.\n<ul>\n<li>Before:\n<pre>grow &lt;- function() {\n  nrow &lt;- 1000\n  x &lt;- NULL\n  for(i in 1:(nrow)) {\n    x &lt;- rbind(x, i:(i+9))\n  }\n  x\n}\n\nsystem.time(grow(), gcFirst=TRUE)<\/pre>\n<\/li>\n<li>After:\n<pre>no.grow &lt;- function() {\n  nrow &lt;- 1000\n  x &lt;- matrix(0, nrow = nrow, ncol = 10)\n  for(i in 1:nrow) {\n    x[i, ] &lt;- i:(i + 9)\n  }\n  x\n}\n\nsystem.time(no.grow(), gcFirst=TRUE)<\/pre>\n<\/li>\n<li>When an element is added to an existing vector, R allocates a new vector of length equal to the current vector plus the additional element. It then copies the existing vector and the new element into the new vector. In contrast overwriting a element in a vector requires just the copying of the replacement elements.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>These are some good programing techniques in general.<\/p>\n<ul>\n<li>Always use parentheses to make groupings explicit.\n<ul>\n<li><code>x &lt; 5 &amp;&amp; y &gt; 10 || z &lt; 6<\/code>\u00a0not clear as to what should be happening\n<pre>x &lt;- 6\ny &lt;- 10\nz &lt;- 5\nw &lt;- 15\n\nx &lt; 5 &amp;&amp; y &gt; 10 || z &lt; 6 &amp;&amp; w &lt; 25      # TRUE\n(x &lt; 5 &amp;&amp; y &gt; 10) || (z &lt; 6 &amp;&amp; w &lt; 25)  # TRUE\nx &lt; 5 &amp;&amp; (y &gt; 10 || z &lt; 6) &amp;&amp; w &lt; 25    # FALSE\n(x &lt; 5 &amp;&amp; y &gt; 10 || z &lt; 6) &amp;&amp; w &lt; 25    # TRUE\nx &lt; 5 &amp;&amp; (y &gt; 10 || z &lt; 6 &amp;&amp; w &lt; 25)    # FALSE<\/pre>\n<\/li>\n<li><code>-2^2<\/code>\u00a0equals -4 not 4 like (-2)^2.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Always use { and } in functions, loops, if, else, and other statements\n<ul>\n<li>Example of ambiguity:\n<pre>test &lt;- function(x, y) {\n  if(x)\n    if(y) 5\n  else 6\n}\n\n(test(TRUE, TRUE))       # [1] 5\n(test(TRUE, FALSE))      # [1] 6\n(test(FALSE, TRUE))      # NULL\n(test(FALSE, FALSE))     # NULL<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Use the\u00a0<code>return()<\/code>\u00a0function at the end of functions.<\/li>\n<li>Always use\u00a0<code>TRUE<\/code>\u00a0and\u00a0<code>FALSE<\/code>\u00a0instead of\u00a0<code>T<\/code>\u00a0and\u00a0<code>F<\/code>.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2><a name=\"Writing_Functions\"><\/a>Writing Functions<\/h2>\n<p>Functions in R can do 3 things<\/p>\n<ol>\n<li>Be passed values<\/li>\n<li>Return a value<\/li>\n<li>Side effects, anything caused that is not the returning of a value. This would be like the text output of\u00a0<code>print()<\/code>\u00a0or the opening of a dvi viewer from<code>print.latex()<\/code>. We are not going to deal with this topic in this lecture.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3><a name=\"The_R_function_Statement\"><\/a>The R\u00a0<code>function<\/code>\u00a0Statement<\/h3>\n<p>The basic R function statement looks like this<br \/>\n<code>FUNname &lt;- function( arglist ) { code }<\/code><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>FUNname is th name that you have selected as you function name.\n<ul>\n<li>You can select any non-reserved word to be you function name.<\/li>\n<li>However you cannot have an function name and a variable name be the same.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>arglist is a coma separated list of 0 or more arguments that can be passed to the function.<\/li>\n<li>code is the statements that perform the actions of the function<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><a name=\"Function_Return_Values\"><\/a>Function Return Values<\/h3>\n<p>Functions are designed to return values. It is call returning because the value is taken from the function and is returned to the calling code.<\/p>\n<ul>\n<li>Functions have 2 ways to return values.\n<ol>\n<li>The value of the last statement evaluated in the function.\n<ul>\n<li>Example:\n<pre>f1 &lt;- function() {\n  10\n}\n\n&gt; f1()\n[1] 10<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ol>\n<li>\n<ol>\n<li>The value passed to the\u00a0<code>return<\/code>\u00a0statement. Calling a return statement always causes the function to return\n<ul>\n<li>Example:\n<pre>f2 &lt;- function() {\n  return(20)\n  10\n}\n\n&gt; f2()\n[1] 20<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3><a name=\"Function_Arguments\"><\/a>Function Arguments<\/h3>\n<p>The function argument statement looks like this<br \/>\n<code>VARname<\/code><br \/>\nor<br \/>\n<code>VARname = VALUE<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Function arguments are how values are passed to the function by the calling code.<\/li>\n<li>By convention the first argument is the main data object being passed to the function. The class of first argument is used for matching S3 methods.<\/li>\n<li>The function arguments are treated like variables inside the functions code.\n<ul>\n<li>Example:\n<pre>f3 &lt;- function(x) {\n  x + 5\n}\n\n&gt; f3(5)\n[1] 10<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Arguments can be set to a default value is the calling code does not explicitly an argument to a value. This is done using the\u00a0<code>VARname = VALUE<\/code>.\n<ul>\n<li>Example:\n<pre>f4 &lt;- function(x, y=5) {\n  x + y\n}\n\n&gt; f4(5)\n[1] 10\n&gt; f4(5,7)\n[1] 12<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>You can test to see if the calling code has set an argument to a value using the test function\u00a0<code>missing<\/code>. Function\u00a0<code>missing(x)<\/code>\u00a0returns a logical\u00a0<code>TRUE<\/code>\u00a0if the value of<code>x<\/code>\u00a0has not been set by the calling code.\n<ul>\n<li>Example:\n<pre>f5 &lt;- function(x) {\n  if( missing(x) ) {\n    return(\"x is missing\")\n  } else {\n    return(\"x is not missing\")\n  }\n}\n\n&gt; f5()\n[1] \"x is missing\"\n&gt; f5(10)\n[1] \"x is not missing\"<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>The arglist can also have a special type of argument\u00a0<code>...<\/code>\u00a0. This is argument can hold a variable number of arguments. In R functions it is mostly used for passing parameters to other functions.\n<ul>\n<li>Example:\n<pre>f6 &lt;- function(z, ...) {\n  print(paste(\"The value of z is\", z, sep=\" \"))\n\n  paste(\"The value of f5(...) is\", f5(...), sep=\" \")\n}\n\n&gt; f6(5, x=3)\n[1] \"The value of x is 5\"\n[1] \"The value of f5(...) is x is not missing\"\n&gt; f6(5)\n[1] \"The value of x is 5\"\n[1] \"The value of f5(...) is x is missing\"\n\nf6.5 &lt;- function(z, ...) {\n  print(paste(\"The value of z is\", z, sep=\" \"))\n\n  b &lt;- list(...)\n  cat(paste(names(b), b, sep=':', collapse=\" \"))\n  cat(\"\\n\")\n}\n\nf6(5)\nf6(5, a=\"sdd\", \"desg\")<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><a name=\"Useful_Functions_for_Use_in_Func\"><\/a>Useful Functions for Use in Functions<\/h3>\n<p>There are many functions that are designed to only be used in other functions. In this section we go over some of the more useful functions.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>The\u00a0<code>as.<\/code>\u00a0family of coercion functions, such as\u00a0<code>as.vector(x)<\/code>,\u00a0<code>as.data.frame(x)<\/code>, or\u00a0<code>as.double(x)<\/code>. These functions are used to change the data type of\u00a0<code>x<\/code>\u00a0to a new data type.\n<ul>\n<li>Example:\n<pre>f7 &lt;-  function(x) {\n  as.character(x)\n}\n\n&gt; class(f7(7))\n[1] \"character\"\n&gt; class(f7(\"a\"))\n[1] \"character\"<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>The\u00a0<code>is.<\/code>\u00a0family of test functions, such as\u00a0<code>is.null()<\/code>,\u00a0<code>is.numeric()<\/code>, and\u00a0<code>is.data.frame()<\/code>. These functions are used to tell what kind of variable that the function has been passed.\n<ul>\n<li>Example:%BR\n<pre>f8 &lt;- function(x) {\n  is.character(x)\n}\n\n&gt; f8(9)\n[1] FALSE\n&gt; f8(\"abc\")\n[1] TRUE<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>The\u00a0<code>on.exit()<\/code>\u00a0function records the expression pass to it and executes that expression after the function exits, either naturally or the result of an error\n<ul>\n<li>Example:\n<pre>f9 &lt;- function() {\n  opar &lt;- par(mai = c(1,1,1,1))\n  on.exit(par(opar))\n  par()$mai\n}\n\npar()$mai     # [1] 1.0627614 0.8543768 0.8543768 0.4376077\nf9()          # [1] 1 1 1 1\npar()$mai     # [1] 1.0627614 0.8543768 0.8543768 0.4376077<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2><a name=\"R_Gotchas\"><\/a>R Gotchas<\/h2>\n<p>R has several &#8216;features&#8217; that can trip up those who are not aware of them.<\/p>\n<h3><a name=\"Environments\"><\/a>Environments<\/h3>\n<ul>\n<li>Environments are the location that R stores its objects (variables, functions, etc.).<\/li>\n<li>All environments (except the global environment) have a parent environment.\n<ul>\n<li>An environment can read from and write to objects in the parent environment. If an object from the parent environment is told to change instead a new object is created in the current environment holding the new value. The new object now masks the object from the parent environment. Use the alternative assignment operator to modify variables in the parent environment\n<pre>a &lt;- 1\ntest &lt;- function() {\n   print(a)\n   a &lt;- 2\n   print(a)\n   invisible(NULL)\n}\ntest()\nprint(a)\ntest2 &lt;- function() {\n   print(a)\n   a &lt;&lt;- 3\n   print(a)\n   invisible(NULL)\n}\ntest2()\nprint(a)<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li>Each call to a function receives it&#8217;s own environment that is a child of the calling environment. When a function returns that environment is destroyed.\n<ul>\n<li>Because of this errors of omission can lead to very odd bugs.\n<ul>\n<li>This is the correct code\n<pre>a &lt;- 5\ntest1 &lt;- function(b=1) {\n   a &lt;- 10 * b\n   if(a &gt; 5) {\n      return(45)\n   }\n   return(b)\n}\n\ntest1()        # [1] 45<\/pre>\n<\/li>\n<li>Here is the same code but a critical line has been commented out leading to a functioning function that produces incorrect output.\n<pre>a &lt;- 5\ntest2 &lt;- function(b=1) {\n   #a &lt;- 10 * b\n   if(a &gt; 5) {\n       return(45)\n   }\n   return(b)\n}\n\ntest2()       # [1] 1<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li>when debugging its a good idea to check to make sure that all of the variables in question have been assigned in the function.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><a name=\"T_and_F_vs_TRUE_and_FALSE\"><\/a><code>T<\/code>\u00a0and\u00a0<code>F<\/code>\u00a0vs.\u00a0<code>TRUE<\/code>\u00a0and\u00a0<code>FALSE<\/code><\/h3>\n<ul>\n<li>Always use\u00a0<code>TRUE<\/code>\u00a0and\u00a0<code>FALSE<\/code>\u00a0instead of\u00a0<code>T<\/code>\u00a0and\u00a0<code>F<\/code><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><a name=\"Object_name_confusion\"><\/a>Object name confusion<\/h3>\n<ul>\n<li>If\u00a0<code>attach<\/code>\u00a0or\u00a0<code>with<\/code>\u00a0functions are used the is a good chance that this will lead to confusion on the users part about what objects are being referenced.\n<ul>\n<li>Lets say we want to add the object\u00a0<code>mod<\/code>\u00a0to column\u00a0<code>a<\/code>\u00a0in the data frame\u00a0<code>junk<\/code>.\n<pre>mod &lt;- 15\njunk &lt;- data.frame(a = 1:10)\n\nwith(junk, a + mod)     # [1] 16 17 18 19 20 21 22 23 24 25<\/pre>\n<\/li>\n<li>What happens if there column in &#8216;junk&#8217; named &#8216;mod&#8217;?\n<pre>mod &lt;- 15\njunk &lt;- data.frame(a = 1:10, mod = 6:15)\n\nwith(junk, a + mod)     #[1]  7  9 11 13 15 17 19 21 23 25<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2><a name=\"Basic_Intro_to_debugging_in_R\"><\/a>Basic Intro to debugging in R<\/h2>\n<p>4 Most important debug functions in R.\u00a0<code>cat()<\/code>,\u00a0<code>debug()<\/code>,\u00a0<code>traceback()<\/code>,\u00a0<code>str()<\/code><\/p>\n<ul>\n<li><code>cat()<\/code>\u00a0&#8211; This is good for determining if a part of the code is being called running.<\/li>\n<li><code>str()<\/code>\u00a0&#8211; This is the key to determining what an object actually contains. It gives a comprehensive summary of the contents of the object. It takes a while to easly read its output but it is invaluable for determining the structure of complex lists.<\/li>\n<li><code>traceback()<\/code>\u00a0&#8211; When a function dies by an error the user can call\u00a0<code>traceback<\/code>. This returns the stack trace at the time of the error. The higher the number the deeper in the call stack the function is.<\/li>\n<li><code>debug()<\/code>\u00a0&#8211; marks a function to call the debugger when ever it is called.\n<ul>\n<li>to advance a line press enter and empty prompt or enter\u00a0<code>n<\/code>.<\/li>\n<li>to continue to the next debugged function call enter\u00a0<code>c<\/code>.<\/li>\n<li>to print a stack trace of all active function calls enter\u00a0<code>where<\/code>.<\/li>\n<li>to quit enter\u00a0<code>Q<\/code>.<\/li>\n<li>anything else entered at the prompt is evaluated as an expression in the current environment.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&#8212;\u00a0<a href=\"http:\/\/biostat.mc.vanderbilt.edu\/wiki\/Main\/CharlesDupont\">CharlesDupont<\/a>\u00a0&#8211; 03 Jun 2005<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to write your own functions and good R programing techniques Good R Programing Techniques Writing Functions The R function Statement Function Return Values Function&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-169","post","type-post","status-publish","format-standard","hentry","category-r"],"_links":{"self":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/comments?post=169"}],"version-history":[{"count":0,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/169\/revisions"}],"wp:attachment":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/media?parent=169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/categories?post=169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/tags?post=169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}