Chapter 24: R Functions
Part 1: What is a Function?
A function is a self-contained block of code that performs a specific task. It can take inputs (called arguments), process them, and return an output.
Why Use Functions?
-
Reusability: Write once, use many times
-
Organization: Break complex problems into smaller pieces
-
Debugging: Test each part independently
-
Readability: Give meaningful names to operations
-
Maintenance: Change code in one place, not everywhere
The Basic Syntax
|
0 1 2 3 4 5 6 7 8 9 10 |
function_name <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>parameter1<span class="token punctuation">,</span> parameter2<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Code that does something</span> <span class="token comment"># ...</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token comment"># Optional, but recommended</span> <span class="token punctuation">}</span> |
Part 2: Your First Functions
A Very Simple Function
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token comment"># A function that says hello</span> say_hello <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Hello, world!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call the function</span> say_hello<span class="token punctuation">(</span><span class="token punctuation">)</span> |
Output: [1] "Hello, world!"
Function with Parameters
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment"># A function that greets a specific person</span> greet <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Hello,"</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> <span class="token string">"!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call with different arguments</span> greet<span class="token punctuation">(</span><span class="token string">"Alice"</span><span class="token punctuation">)</span> greet<span class="token punctuation">(</span><span class="token string">"Bob"</span><span class="token punctuation">)</span> greet<span class="token punctuation">(</span><span class="token string">"Charlie"</span><span class="token punctuation">)</span> |
Output:
|
0 1 2 3 4 5 6 7 8 |
[1] "Hello, Alice !" [1] "Hello, Bob !" [1] "Hello, Charlie !" |
Function with Return Value
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="token comment"># A function that adds two numbers</span> add_numbers <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> x <span class="token operator">+</span> y return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Use the function</span> sum <span class="token operator"><-</span> add_numbers<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"5 + 3 ="</span><span class="token punctuation">,</span> sum<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># You can also use it directly in expressions</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"10 + 20 ="</span><span class="token punctuation">,</span> add_numbers<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Output:
|
0 1 2 3 4 5 6 7 |
[1] "5 + 3 = 8" [1] "10 + 20 = 30" |
Part 3: Understanding Return Values
Implicit vs. Explicit Return
In R, the last evaluated expression is automatically returned:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token comment"># Implicit return (last expression)</span> multiply <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> x <span class="token operator">*</span> y <span class="token comment"># This value is returned automatically</span> <span class="token punctuation">}</span> result <span class="token operator"><-</span> multiply<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token comment"># 20</span> |
But it’s often clearer to use return():
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token comment"># Explicit return (clearer intent)</span> multiply <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>x <span class="token operator">*</span> y<span class="token punctuation">)</span> <span class="token comment"># Explicitly state what's returned</span> <span class="token punctuation">}</span> |
Returning Multiple Values
Functions can only return one object, but that object can be a list containing multiple values:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<span class="token comment"># Function that returns multiple statistics</span> calculate_stats <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> <span class="token punctuation">{</span> mean_val <span class="token operator"><-</span> mean<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> median_val <span class="token operator"><-</span> median<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> min_val <span class="token operator"><-</span> min<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> max_val <span class="token operator"><-</span> max<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> sd_val <span class="token operator"><-</span> sd<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> <span class="token comment"># Return as a list</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span> mean <span class="token operator">=</span> mean_val<span class="token punctuation">,</span> median <span class="token operator">=</span> median_val<span class="token punctuation">,</span> min <span class="token operator">=</span> min_val<span class="token punctuation">,</span> max <span class="token operator">=</span> max_val<span class="token punctuation">,</span> sd <span class="token operator">=</span> sd_val<span class="token punctuation">,</span> count <span class="token operator">=</span> length<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Use the function</span> data <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">67</span><span class="token punctuation">,</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token number">89</span><span class="token punctuation">,</span> <span class="token number">34</span><span class="token punctuation">,</span> <span class="token number">56</span><span class="token punctuation">)</span> stats <span class="token operator"><-</span> calculate_stats<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Access individual results</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Mean:"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>mean<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Median:"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>median<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Range:"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>min<span class="token punctuation">,</span> <span class="token string">"-"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>max<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Standard deviation:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>sd<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Part 4: Parameter Types and Default Values
Default Parameter Values
You can give parameters default values that are used if the caller doesn’t provide them:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token comment"># Function with default parameters</span> create_email <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> domain <span class="token operator">=</span> <span class="token string">"example.com"</span><span class="token punctuation">,</span> greeting <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> email <span class="token operator"><-</span> paste0<span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"@"</span><span class="token punctuation">,</span> domain<span class="token punctuation">)</span> message <span class="token operator"><-</span> paste<span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> name<span class="token punctuation">,</span> <span class="token string">"! Your email is"</span><span class="token punctuation">,</span> email<span class="token punctuation">)</span> return<span class="token punctuation">(</span>message<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call with different combinations</span> print<span class="token punctuation">(</span>create_email<span class="token punctuation">(</span><span class="token string">"alice"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Uses both defaults</span> print<span class="token punctuation">(</span>create_email<span class="token punctuation">(</span><span class="token string">"bob"</span><span class="token punctuation">,</span> <span class="token string">"company.org"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Custom domain</span> print<span class="token punctuation">(</span>create_email<span class="token punctuation">(</span><span class="token string">"charlie"</span><span class="token punctuation">,</span> <span class="token string">"school.edu"</span><span class="token punctuation">,</span> <span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Custom everything</span> |
Output:
|
0 1 2 3 4 5 6 7 8 |
[1] "Hello alice ! Your email is alice@example.com" [1] "Hello bob ! Your email is bob@company.org" [1] "Hi charlie ! Your email is charlie@school.edu" |
Named Arguments
You can specify arguments by name, which is especially useful when there are many parameters:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span class="token comment"># Function with multiple parameters</span> plot_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> title <span class="token operator">=</span> <span class="token string">"Plot"</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token string">"blue"</span><span class="token punctuation">,</span> size <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> type <span class="token operator">=</span> <span class="token string">"p"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"Plotting"</span><span class="token punctuation">,</span> length<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"points\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Title:"</span><span class="token punctuation">,</span> title<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Color:"</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Point size:"</span><span class="token punctuation">,</span> size<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Plot type:"</span><span class="token punctuation">,</span> type<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token comment"># In a real function, this would create a plot</span> <span class="token punctuation">}</span> <span class="token comment"># Call with named arguments (order doesn't matter)</span> plot_data<span class="token punctuation">(</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token string">"red"</span><span class="token punctuation">,</span> title <span class="token operator">=</span> <span class="token string">"My Scatter Plot"</span><span class="token punctuation">,</span> size <span class="token operator">=</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token comment"># You can skip parameters with defaults</span> plot_data<span class="token punctuation">(</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">5</span><span class="token punctuation">,</span> y <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> type <span class="token operator">=</span> <span class="token string">"l"</span> <span class="token comment"># Only specify what you need</span> <span class="token punctuation">)</span> |
Part 5: Variable Scope
Understanding scope is crucial when working with functions. Variables inside functions are separate from variables outside.
Local vs. Global Variables
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment"># Global variable (outside any function)</span> global_var <span class="token operator"><-</span> <span class="token string">"I'm global!"</span> test_scope <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Local variable (inside the function)</span> local_var <span class="token operator"><-</span> <span class="token string">"I'm local!"</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Inside function - global_var:"</span><span class="token punctuation">,</span> global_var<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Inside function - local_var:"</span><span class="token punctuation">,</span> local_var<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Modify global variable? No - creates local copy!</span> global_var <span class="token operator"><-</span> <span class="token string">"Changed inside function"</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Inside after change:"</span><span class="token punctuation">,</span> global_var<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call the function</span> test_scope<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Outside the function</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Outside - global_var:"</span><span class="token punctuation">,</span> global_var<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># This would cause an error:</span> <span class="token comment"># print(local_var) # Error: object 'local_var' not found</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 |
[1] "Inside function - global_var: I'm global!" [1] "Inside function - local_var: I'm local!" [1] "Inside after change: Changed inside function" [1] "Outside - global_var: I'm global!" |
The Super Assignment Operator (<<-)
If you really need to modify a global variable from inside a function, use <<-:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
counter <span class="token operator"><-</span> <span class="token number">0</span> increment_counter <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> counter <span class="token operator"><<-</span> counter <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Modifies the global counter</span> return<span class="token punctuation">(</span>counter<span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>increment_counter<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 1</span> print<span class="token punctuation">(</span>increment_counter<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 2</span> print<span class="token punctuation">(</span>increment_counter<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 3</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Global counter is now:"</span><span class="token punctuation">,</span> counter<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 3</span> |
Warning: Modifying global variables from inside functions is generally considered bad practice. It makes code harder to debug and understand.
Part 6: Practical Examples
Example 1: Temperature Converter
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="token comment"># Comprehensive temperature conversion functions</span> convert_temperature <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> from <span class="token operator">=</span> <span class="token string">"celsius"</span><span class="token punctuation">,</span> to <span class="token operator">=</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Convert to Celsius first (as intermediate)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>from <span class="token operator">==</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> celsius <span class="token operator"><-</span> <span class="token punctuation">(</span>value <span class="token operator">-</span> <span class="token number">32</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">5</span><span class="token operator">/</span><span class="token number">9</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>from <span class="token operator">==</span> <span class="token string">"kelvin"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> celsius <span class="token operator"><-</span> value <span class="token operator">-</span> <span class="token number">273.15</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>from <span class="token operator">==</span> <span class="token string">"celsius"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> celsius <span class="token operator"><-</span> value <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Unknown 'from' unit. Use 'celsius', 'fahrenheit', or 'kelvin'"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Convert from Celsius to target unit</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>to <span class="token operator">==</span> <span class="token string">"celsius"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> celsius <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>to <span class="token operator">==</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> celsius <span class="token operator">*</span> <span class="token number">9</span><span class="token operator">/</span><span class="token number">5</span> <span class="token operator">+</span> <span class="token number">32</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>to <span class="token operator">==</span> <span class="token string">"kelvin"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> celsius <span class="token operator">+</span> <span class="token number">273.15</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Unknown 'to' unit. Use 'celsius', 'fahrenheit', or 'kelvin'"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Round to 2 decimal places for readability</span> result <span class="token operator"><-</span> round<span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test the function</span> print<span class="token punctuation">(</span>convert_temperature<span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token string">"celsius"</span><span class="token punctuation">,</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 212°F</span> print<span class="token punctuation">(</span>convert_temperature<span class="token punctuation">(</span><span class="token number">32</span><span class="token punctuation">,</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">,</span> <span class="token string">"celsius"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 0°C</span> print<span class="token punctuation">(</span>convert_temperature<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"celsius"</span><span class="token punctuation">,</span> <span class="token string">"kelvin"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 273.15K</span> print<span class="token punctuation">(</span>convert_temperature<span class="token punctuation">(</span><span class="token number">300</span><span class="token punctuation">,</span> <span class="token string">"kelvin"</span><span class="token punctuation">,</span> <span class="token string">"fahrenheit"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># About 80.33°F</span> |
Example 2: Data Quality Report
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
<span class="token comment"># Function to generate a quality report for a dataset</span> quality_report <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> dataset_name <span class="token operator">=</span> <span class="token string">"Dataset"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Initialize results list</span> report <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Basic info</span> report<span class="token operator">$</span>name <span class="token operator"><-</span> dataset_name report<span class="token operator">$</span>rows <span class="token operator"><-</span> nrow<span class="token punctuation">(</span>data<span class="token punctuation">)</span> report<span class="token operator">$</span>columns <span class="token operator"><-</span> ncol<span class="token punctuation">(</span>data<span class="token punctuation">)</span> report<span class="token operator">$</span>column_names <span class="token operator"><-</span> names<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Check for missing values</span> report<span class="token operator">$</span>total_missing <span class="token operator"><-</span> sum<span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> report<span class="token operator">$</span>rows_complete <span class="token operator"><-</span> sum<span class="token punctuation">(</span>complete.cases<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Column-specific stats</span> column_stats <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>col <span class="token keyword">in</span> names<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> col_data <span class="token operator"><-</span> data<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> stats <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>type <span class="token operator"><-</span> class<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> stats<span class="token operator">$</span>missing <span class="token operator"><-</span> sum<span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>missing_pct <span class="token operator"><-</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>missing <span class="token operator">/</span> report<span class="token operator">$</span>rows <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.numeric<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stats<span class="token operator">$</span>min <span class="token operator"><-</span> min<span class="token punctuation">(</span>col_data<span class="token punctuation">,</span> na.rm <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>max <span class="token operator"><-</span> max<span class="token punctuation">(</span>col_data<span class="token punctuation">,</span> na.rm <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>mean <span class="token operator"><-</span> mean<span class="token punctuation">(</span>col_data<span class="token punctuation">,</span> na.rm <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>sd <span class="token operator"><-</span> sd<span class="token punctuation">(</span>col_data<span class="token punctuation">,</span> na.rm <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>unique <span class="token operator"><-</span> length<span class="token punctuation">(</span>unique<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.character<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span> <span class="token operator">||</span> is.factor<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stats<span class="token operator">$</span>unique <span class="token operator"><-</span> length<span class="token punctuation">(</span>unique<span class="token punctuation">(</span>col_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>stats<span class="token operator">$</span>unique <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stats<span class="token operator">$</span>frequencies <span class="token operator"><-</span> table<span class="token punctuation">(</span>col_data<span class="token punctuation">,</span> useNA <span class="token operator">=</span> <span class="token string">"ifany"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> column_stats<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><-</span> stats <span class="token punctuation">}</span> report<span class="token operator">$</span>columns_detail <span class="token operator"><-</span> column_stats <span class="token comment"># Print summary</span> cat<span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">,</span> paste<span class="token punctuation">(</span>rep<span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"QUALITY REPORT:"</span><span class="token punctuation">,</span> dataset_name<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span>paste<span class="token punctuation">(</span>rep<span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Dimensions:"</span><span class="token punctuation">,</span> report<span class="token operator">$</span>rows<span class="token punctuation">,</span> <span class="token string">"rows x"</span><span class="token punctuation">,</span> report<span class="token operator">$</span>columns<span class="token punctuation">,</span> <span class="token string">"columns\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Complete rows:"</span><span class="token punctuation">,</span> report<span class="token operator">$</span>rows_complete<span class="token punctuation">,</span> <span class="token string">"("</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>report<span class="token operator">$</span>rows_complete<span class="token operator">/</span>report<span class="token operator">$</span>rows<span class="token operator">*</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%)\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Total missing values:"</span><span class="token punctuation">,</span> report<span class="token operator">$</span>total_missing<span class="token punctuation">,</span> <span class="token string">"\n\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Column Details:\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span>paste<span class="token punctuation">(</span>rep<span class="token punctuation">(</span><span class="token string">"-"</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>col <span class="token keyword">in</span> names<span class="token punctuation">(</span>column_stats<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> s <span class="token operator"><-</span> column_stats<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> cat<span class="token punctuation">(</span>sprintf<span class="token punctuation">(</span><span class="token string">"%-20s: %s, missing: %d (%s%%)"</span><span class="token punctuation">,</span> col<span class="token punctuation">,</span> s<span class="token operator">$</span>type<span class="token punctuation">,</span> s<span class="token operator">$</span>missing<span class="token punctuation">,</span> s<span class="token operator">$</span>missing_pct<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.null<span class="token punctuation">(</span>s<span class="token operator">$</span>min<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span>sprintf<span class="token punctuation">(</span><span class="token string">", range: [%.2f, %.2f]"</span><span class="token punctuation">,</span> s<span class="token operator">$</span>min<span class="token punctuation">,</span> s<span class="token operator">$</span>max<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.null<span class="token punctuation">(</span>s<span class="token operator">$</span>unique<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span>sprintf<span class="token punctuation">(</span><span class="token string">", unique: %d"</span><span class="token punctuation">,</span> s<span class="token operator">$</span>unique<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> cat<span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.null<span class="token punctuation">(</span>s<span class="token operator">$</span>frequencies<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">" Frequencies:\n"</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>val <span class="token keyword">in</span> names<span class="token punctuation">(</span>s<span class="token operator">$</span>frequencies<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">" <NA>: "</span><span class="token punctuation">,</span> s<span class="token operator">$</span>frequencies<span class="token punctuation">[</span>is.na<span class="token punctuation">(</span>names<span class="token punctuation">(</span>s<span class="token operator">$</span>frequencies<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">,</span> val<span class="token punctuation">,</span> <span class="token string">": "</span><span class="token punctuation">,</span> s<span class="token operator">$</span>frequencies<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> invisible<span class="token punctuation">(</span>report<span class="token punctuation">)</span> <span class="token comment"># Return invisibly (won't print automatically)</span> <span class="token punctuation">}</span> <span class="token comment"># Test with sample data</span> test_data <span class="token operator"><-</span> data.frame<span class="token punctuation">(</span> id <span class="token operator">=</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">100</span><span class="token punctuation">,</span> age <span class="token operator">=</span> c<span class="token punctuation">(</span>sample<span class="token punctuation">(</span><span class="token number">18</span><span class="token operator">:</span><span class="token number">80</span><span class="token punctuation">,</span> <span class="token number">95</span><span class="token punctuation">,</span> replace <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span><span class="token punctuation">,</span> rep<span class="token punctuation">(</span><span class="token keyword">NA</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> gender <span class="token operator">=</span> sample<span class="token punctuation">(</span>c<span class="token punctuation">(</span><span class="token string">"M"</span><span class="token punctuation">,</span> <span class="token string">"F"</span><span class="token punctuation">,</span> <span class="token keyword">NA</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> replace <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">,</span> prob <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">0.45</span><span class="token punctuation">,</span> <span class="token number">0.45</span><span class="token punctuation">,</span> <span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> score <span class="token operator">=</span> round<span class="token punctuation">(</span>rnorm<span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> mean <span class="token operator">=</span> <span class="token number">75</span><span class="token punctuation">,</span> sd <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stringsAsFactors <span class="token operator">=</span> <span class="token boolean">FALSE</span> <span class="token punctuation">)</span> report <span class="token operator"><-</span> quality_report<span class="token punctuation">(</span>test_data<span class="token punctuation">,</span> <span class="token string">"Test Dataset"</span><span class="token punctuation">)</span> |
Example 3: Statistical Summary Function
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<span class="token comment"># Comprehensive statistical summary function</span> enhanced_summary <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> na.rm <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">,</span> output <span class="token operator">=</span> <span class="token string">"both"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Input validation</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Input must be numeric"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Basic statistics</span> stats <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>n <span class="token operator"><-</span> length<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>n_missing <span class="token operator"><-</span> sum<span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>n_valid <span class="token operator"><-</span> stats<span class="token operator">$</span>n <span class="token operator">-</span> stats<span class="token operator">$</span>n_missing <span class="token keyword">if</span> <span class="token punctuation">(</span>na.rm<span class="token punctuation">)</span> <span class="token punctuation">{</span> x <span class="token operator"><-</span> x<span class="token punctuation">[</span><span class="token operator">!</span>is.na<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stats<span class="token operator">$</span>min <span class="token operator"><-</span> min<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>max <span class="token operator"><-</span> max<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>mean <span class="token operator"><-</span> mean<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>median <span class="token operator"><-</span> median<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>sd <span class="token operator"><-</span> sd<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>var <span class="token operator"><-</span> var<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>q1 <span class="token operator"><-</span> quantile<span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token number">0.25</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>q3 <span class="token operator"><-</span> quantile<span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token number">0.75</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>iqr <span class="token operator"><-</span> IQR<span class="token punctuation">(</span>x<span class="token punctuation">)</span> stats<span class="token operator">$</span>range <span class="token operator"><-</span> stats<span class="token operator">$</span>max <span class="token operator">-</span> stats<span class="token operator">$</span>min <span class="token comment"># Additional statistics</span> stats<span class="token operator">$</span>skewness <span class="token operator"><-</span> sum<span class="token punctuation">(</span><span class="token punctuation">(</span>x <span class="token operator">-</span> stats<span class="token operator">$</span>mean<span class="token punctuation">)</span><span class="token operator">^</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">*</span> stats<span class="token operator">$</span>sd<span class="token operator">^</span><span class="token number">3</span><span class="token punctuation">)</span> stats<span class="token operator">$</span>kurtosis <span class="token operator"><-</span> sum<span class="token punctuation">(</span><span class="token punctuation">(</span>x <span class="token operator">-</span> stats<span class="token operator">$</span>mean<span class="token punctuation">)</span><span class="token operator">^</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">*</span> stats<span class="token operator">$</span>sd<span class="token operator">^</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">3</span> <span class="token comment"># Outliers (using 1.5 * IQR rule)</span> lower_bound <span class="token operator"><-</span> stats<span class="token operator">$</span>q1 <span class="token operator">-</span> <span class="token number">1.5</span> <span class="token operator">*</span> stats<span class="token operator">$</span>iqr upper_bound <span class="token operator"><-</span> stats<span class="token operator">$</span>q3 <span class="token operator">+</span> <span class="token number">1.5</span> <span class="token operator">*</span> stats<span class="token operator">$</span>iqr stats<span class="token operator">$</span>outliers <span class="token operator"><-</span> sum<span class="token punctuation">(</span>x <span class="token operator"><</span> lower_bound <span class="token operator">|</span> x <span class="token operator">></span> upper_bound<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"No valid observations after removing NAs"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token keyword">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Output formatting</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>output <span class="token operator">==</span> <span class="token string">"text"</span> <span class="token operator">||</span> output <span class="token operator">==</span> <span class="token string">"both"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">,</span> paste<span class="token punctuation">(</span>rep<span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"STATISTICAL SUMMARY\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span>paste<span class="token punctuation">(</span>rep<span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"N:"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>n<span class="token punctuation">,</span> <span class="token string">"(missing:"</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>n_missing<span class="token punctuation">,</span> <span class="token string">")\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nCentral Tendency:\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Mean: "</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>mean<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Median: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>median<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nDispersion:\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" SD: "</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>sd<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Variance: "</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>var<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Range: ["</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>min<span class="token punctuation">,</span> <span class="token string">", "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>max<span class="token punctuation">,</span> <span class="token string">"]\n"</span><span class="token punctuation">,</span> sep <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" IQR: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>iqr<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nQuartiles:\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Q1: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>q1<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Q2: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>median<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Q3: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>q3<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nShape:\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Skewness: "</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>skewness<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> ifelse<span class="token punctuation">(</span>abs<span class="token punctuation">(</span>stats<span class="token operator">$</span>skewness<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"(highly skewed)"</span><span class="token punctuation">,</span> ifelse<span class="token punctuation">(</span>abs<span class="token punctuation">(</span>stats<span class="token operator">$</span>skewness<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token string">"(moderately skewed)"</span><span class="token punctuation">,</span> <span class="token string">"(approximately symmetric)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Kurtosis: "</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>stats<span class="token operator">$</span>kurtosis<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> ifelse<span class="token punctuation">(</span>stats<span class="token operator">$</span>kurtosis <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"(leptokurtic/heavy-tailed)"</span><span class="token punctuation">,</span> ifelse<span class="token punctuation">(</span>stats<span class="token operator">$</span>kurtosis <span class="token operator"><</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"(platykurtic/light-tailed)"</span><span class="token punctuation">,</span> <span class="token string">"(mesokurtic/normal-like)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nOutliers: "</span><span class="token punctuation">,</span> stats<span class="token operator">$</span>outliers<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>output <span class="token operator">==</span> <span class="token string">"list"</span> <span class="token operator">||</span> output <span class="token operator">==</span> <span class="token string">"both"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>stats<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment"># Test the function</span> set.seed<span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span> data <span class="token operator"><-</span> c<span class="token punctuation">(</span>rnorm<span class="token punctuation">(</span><span class="token number">95</span><span class="token punctuation">,</span> mean <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">,</span> sd <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span> rnorm<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> mean <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">,</span> sd <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Add some outliers</span> results <span class="token operator"><-</span> enhanced_summary<span class="token punctuation">(</span>data<span class="token punctuation">,</span> output <span class="token operator">=</span> <span class="token string">"both"</span><span class="token punctuation">)</span> |
Part 7: Functions with Variable Arguments
The … (ellipsis) Argument
The ... allows functions to accept any number of additional arguments:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment"># Function that can take any number of arguments</span> sum_all <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> args <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> total <span class="token operator"><-</span> <span class="token number">0</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>arg <span class="token keyword">in</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.numeric<span class="token punctuation">(</span>arg<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> total <span class="token operator"><-</span> total <span class="token operator">+</span> arg <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"Non-numeric argument ignored: "</span><span class="token punctuation">,</span> arg<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>total<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call with different numbers of arguments</span> print<span class="token punctuation">(</span>sum_all<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 6</span> print<span class="token punctuation">(</span>sum_all<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 150</span> print<span class="token punctuation">(</span>sum_all<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 10 with warning</span> |
Passing … to Other Functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="token comment"># Create a plotting function that passes ... to the base plot function</span> flexible_plot <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Calculate some statistics</span> correlation <span class="token operator"><-</span> cor<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token comment"># Create the plot with additional arguments passed through ...</span> plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> main <span class="token operator">=</span> paste<span class="token punctuation">(</span><span class="token string">"Scatter Plot (r ="</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>correlation<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token comment"># Any additional arguments (col, pch, cex, etc.) are passed to plot</span> <span class="token punctuation">}</span> <span class="token comment"># Use the function with different options</span> x <span class="token operator"><-</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span> y <span class="token operator"><-</span> <span class="token number">2</span><span class="token operator">*</span>x <span class="token operator">+</span> rnorm<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> flexible_plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token comment"># Default</span> flexible_plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> col <span class="token operator">=</span> <span class="token string">"red"</span><span class="token punctuation">,</span> pch <span class="token operator">=</span> <span class="token number">16</span><span class="token punctuation">,</span> cex <span class="token operator">=</span> <span class="token number">1.5</span><span class="token punctuation">)</span> <span class="token comment"># Customized</span> |
Part 8: Recursive Functions
A function that calls itself is called recursive. This is useful for problems that can be broken into smaller, similar subproblems.
Example: Factorial
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="token comment"># Recursive factorial function</span> factorial_recursive <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Base case</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator"><=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Recursive case</span> return<span class="token punctuation">(</span>n <span class="token operator">*</span> factorial_recursive<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Compare with built-in</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token string">"! ="</span><span class="token punctuation">,</span> factorial_recursive<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"(built-in:"</span><span class="token punctuation">,</span> factorial<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">")\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Example: Fibonacci Sequence
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<span class="token comment"># Recursive Fibonacci (beautiful but inefficient for large n)</span> fibonacci <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Base cases</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># Recursive case</span> return<span class="token punctuation">(</span>fibonacci<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> fibonacci<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># More efficient version with memoization</span> fibonacci_memo <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">,</span> memo <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># Check if already calculated</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>memo<span class="token punctuation">)</span> <span class="token operator">>=</span> n <span class="token operator">&&</span> <span class="token operator">!</span>is.na<span class="token punctuation">(</span>memo<span class="token punctuation">[</span>n<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>memo<span class="token punctuation">[</span>n<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Calculate and store</span> result <span class="token operator"><-</span> fibonacci_memo<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span> memo<span class="token punctuation">)</span> <span class="token operator">+</span> fibonacci_memo<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">,</span> memo<span class="token punctuation">)</span> <span class="token comment"># Update memo (simplified - in practice, need to pass back up)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Compare performance</span> system.time<span class="token punctuation">(</span>fibonacci<span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Slow</span> system.time<span class="token punctuation">(</span>fibonacci_memo<span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Fast</span> |
Example: Directory Tree
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment"># Function to list files recursively with indentation</span> list_files_recursive <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>path <span class="token operator">=</span> <span class="token string">"."</span><span class="token punctuation">,</span> indent <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> items <span class="token operator"><-</span> list.files<span class="token punctuation">(</span>path<span class="token punctuation">,</span> full.names <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>item <span class="token keyword">in</span> items<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>file.info<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token operator">$</span>isdir<span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span>indent<span class="token punctuation">,</span> <span class="token string">"📁 "</span><span class="token punctuation">,</span> basename<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"/\n"</span><span class="token punctuation">,</span> sep <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span> list_files_recursive<span class="token punctuation">(</span>item<span class="token punctuation">,</span> paste0<span class="token punctuation">(</span>indent<span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> size <span class="token operator"><-</span> file.info<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token operator">$</span>size cat<span class="token punctuation">(</span>indent<span class="token punctuation">,</span> <span class="token string">"📄 "</span><span class="token punctuation">,</span> basename<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">" ("</span><span class="token punctuation">,</span> format<span class="token punctuation">(</span>size<span class="token punctuation">,</span> big.mark <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">" bytes)\n"</span><span class="token punctuation">,</span> sep <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment"># List current directory (be careful with large directories!)</span> <span class="token comment"># list_files_recursive(".")</span> |
Part 9: Functions as Objects
In R, functions are first-class objects. You can assign them to variables, pass them as arguments, and return them from other functions.
Storing Functions in Lists
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment"># Create a list of mathematical operations</span> operations <span class="token operator"><-</span> list<span class="token punctuation">(</span> add <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> x <span class="token operator">+</span> y<span class="token punctuation">,</span> subtract <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> x <span class="token operator">-</span> y<span class="token punctuation">,</span> multiply <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> x <span class="token operator">*</span> y<span class="token punctuation">,</span> divide <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>y <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"Division by zero"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span><span class="token keyword">NA</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>x <span class="token operator">/</span> y<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> power <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> x<span class="token operator">^</span>y <span class="token punctuation">)</span> <span class="token comment"># Use the functions</span> x <span class="token operator"><-</span> <span class="token number">10</span> y <span class="token operator"><-</span> <span class="token number">3</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>op_name <span class="token keyword">in</span> names<span class="token punctuation">(</span>operations<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> operations<span class="token punctuation">[</span><span class="token punctuation">[</span>op_name<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> cat<span class="token punctuation">(</span>op_name<span class="token punctuation">,</span> <span class="token string">":"</span><span class="token punctuation">,</span> x<span class="token punctuation">,</span> <span class="token string">"and"</span><span class="token punctuation">,</span> y<span class="token punctuation">,</span> <span class="token string">"="</span><span class="token punctuation">,</span> result<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Function Factory (Function that Returns Functions)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment"># Create a function that generates power functions</span> create_power_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>exponent<span class="token punctuation">)</span> <span class="token punctuation">{</span> power_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>x<span class="token operator">^</span>exponent<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>power_function<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create specific power functions</span> square <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> cube <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> quadratic <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment"># Use them</span> numbers <span class="token operator"><-</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">5</span> cat<span class="token punctuation">(</span><span class="token string">"Squares:"</span><span class="token punctuation">,</span> square<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Cubes:"</span><span class="token punctuation">,</span> cube<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Fourth powers:"</span><span class="token punctuation">,</span> quadratic<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> |
Function that Takes Functions as Arguments
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="token comment"># Apply a function to each column of a data frame</span> apply_to_columns <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>df<span class="token punctuation">,</span> func<span class="token punctuation">)</span> <span class="token punctuation">{</span> results <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>col_name <span class="token keyword">in</span> names<span class="token punctuation">(</span>df<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.numeric<span class="token punctuation">(</span>df<span class="token punctuation">[</span><span class="token punctuation">[</span>col_name<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> results<span class="token punctuation">[</span><span class="token punctuation">[</span>col_name<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><-</span> func<span class="token punctuation">(</span>df<span class="token punctuation">[</span><span class="token punctuation">[</span>col_name<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"Column '"</span><span class="token punctuation">,</span> col_name<span class="token punctuation">,</span> <span class="token string">"' is not numeric, skipping"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>results<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create sample data</span> df <span class="token operator"><-</span> data.frame<span class="token punctuation">(</span> age <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">35</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">)</span><span class="token punctuation">,</span> score <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">85</span><span class="token punctuation">,</span> <span class="token number">92</span><span class="token punctuation">,</span> <span class="token number">78</span><span class="token punctuation">,</span> <span class="token number">88</span><span class="token punctuation">,</span> <span class="token number">95</span><span class="token punctuation">)</span><span class="token punctuation">,</span> income <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">50000</span><span class="token punctuation">,</span> <span class="token number">60000</span><span class="token punctuation">,</span> <span class="token number">75000</span><span class="token punctuation">,</span> <span class="token number">55000</span><span class="token punctuation">,</span> <span class="token number">80000</span><span class="token punctuation">)</span><span class="token punctuation">,</span> name <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token string">"Alice"</span><span class="token punctuation">,</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token string">"Charlie"</span><span class="token punctuation">,</span> <span class="token string">"Diana"</span><span class="token punctuation">,</span> <span class="token string">"Eve"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stringsAsFactors <span class="token operator">=</span> <span class="token boolean">FALSE</span> <span class="token punctuation">)</span> <span class="token comment"># Apply different functions</span> means <span class="token operator"><-</span> apply_to_columns<span class="token punctuation">(</span>df<span class="token punctuation">,</span> mean<span class="token punctuation">)</span> sds <span class="token operator"><-</span> apply_to_columns<span class="token punctuation">(</span>df<span class="token punctuation">,</span> sd<span class="token punctuation">)</span> ranges <span class="token operator"><-</span> apply_to_columns<span class="token punctuation">(</span>df<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> max<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">-</span> min<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Means:\n"</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>means<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nStandard Deviations:\n"</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>sds<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"\nRanges:\n"</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>ranges<span class="token punctuation">)</span> |
Part 10: Error Handling in Functions
Robust functions should handle errors gracefully.
Using stop() for Errors
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment"># Function with input validation</span> divide_safely <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Both arguments must be numeric"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>b <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Division by zero is not allowed"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>a <span class="token operator">/</span> b<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test</span> tryCatch<span class="token punctuation">(</span><span class="token punctuation">{</span> print<span class="token punctuation">(</span>divide_safely<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>divide_safely<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> error <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"Error caught:"</span><span class="token punctuation">,</span> e<span class="token operator">$</span>message<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> |
Using warning() and message()
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<span class="token comment"># Function with warnings</span> calculate_bmi <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>weight_kg<span class="token punctuation">,</span> height_m<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>weight_kg<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>height_m<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Weight and height must be numeric"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>weight_kg <span class="token operator"><=</span> <span class="token number">0</span> <span class="token operator">||</span> height_m <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Weight and height must be positive"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> bmi <span class="token operator"><-</span> weight_kg <span class="token operator">/</span> <span class="token punctuation">(</span>height_m<span class="token operator">^</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># Add warnings for extreme values</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>bmi <span class="token operator"><</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"BMI is extremely low (severe thinness)"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>bmi <span class="token operator">></span> <span class="token number">40</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> warning<span class="token punctuation">(</span><span class="token string">"BMI is extremely high (severe obesity)"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Informative message</span> message<span class="token punctuation">(</span><span class="token string">"BMI calculated successfully"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>round<span class="token punctuation">(</span>bmi<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test</span> print<span class="token punctuation">(</span>calculate_bmi<span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">1.75</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>calculate_bmi<span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">1.6</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>calculate_bmi<span class="token punctuation">(</span><span class="token number">120</span><span class="token punctuation">,</span> <span class="token number">1.5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Comprehensive Error Handling with tryCatch
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<span class="token comment"># Robust file reading function</span> safe_read_csv <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>file_path<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> tryCatch<span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token comment"># Attempt to read the file</span> data <span class="token operator"><-</span> read.csv<span class="token punctuation">(</span>file_path<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token comment"># Return success with data</span> list<span class="token punctuation">(</span> success <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">,</span> data <span class="token operator">=</span> data<span class="token punctuation">,</span> message <span class="token operator">=</span> paste<span class="token punctuation">(</span><span class="token string">"Successfully read"</span><span class="token punctuation">,</span> nrow<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"rows"</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> warning <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>w<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Handle warnings (still return data but with warning message)</span> data <span class="token operator"><-</span> read.csv<span class="token punctuation">(</span>file_path<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> list<span class="token punctuation">(</span> success <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">,</span> data <span class="token operator">=</span> data<span class="token punctuation">,</span> message <span class="token operator">=</span> paste<span class="token punctuation">(</span><span class="token string">"Read with warning:"</span><span class="token punctuation">,</span> w<span class="token operator">$</span>message<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> error <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Handle errors</span> list<span class="token punctuation">(</span> success <span class="token operator">=</span> <span class="token boolean">FALSE</span><span class="token punctuation">,</span> data <span class="token operator">=</span> <span class="token keyword">NULL</span><span class="token punctuation">,</span> message <span class="token operator">=</span> paste<span class="token punctuation">(</span><span class="token string">"Error:"</span><span class="token punctuation">,</span> e<span class="token operator">$</span>message<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> finally <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment"># This runs whether success or failure</span> message<span class="token punctuation">(</span><span class="token string">"File reading attempt completed"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test with different scenarios</span> <span class="token comment"># Create a test file</span> write.csv<span class="token punctuation">(</span>mtcars<span class="token punctuation">,</span> <span class="token string">"test.csv"</span><span class="token punctuation">,</span> row.names <span class="token operator">=</span> <span class="token boolean">FALSE</span><span class="token punctuation">)</span> <span class="token comment"># Test successful read</span> result <span class="token operator"><-</span> safe_read_csv<span class="token punctuation">(</span><span class="token string">"test.csv"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token operator">$</span>success<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>result<span class="token operator">$</span>message<span class="token punctuation">)</span> print<span class="token punctuation">(</span>head<span class="token punctuation">(</span>result<span class="token operator">$</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test non-existent file</span> result <span class="token operator"><-</span> safe_read_csv<span class="token punctuation">(</span><span class="token string">"nonexistent.csv"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>result<span class="token operator">$</span>success<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>result<span class="token operator">$</span>message<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Part 11: Debugging Functions
Using browser() for Interactive Debugging
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="token comment"># Function with debugging</span> complex_calculation <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span> <span class="token punctuation">{</span> result1 <span class="token operator"><-</span> x <span class="token operator">*</span> y result2 <span class="token operator"><-</span> result1 <span class="token operator">+</span> z <span class="token comment"># Insert breakpoint</span> browser<span class="token punctuation">(</span><span class="token punctuation">)</span> result3 <span class="token operator"><-</span> result2 <span class="token operator">/</span> x final_result <span class="token operator"><-</span> result3 <span class="token operator">-</span> y return<span class="token punctuation">(</span>final_result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Run the function - execution will pause at browser()</span> <span class="token comment"># result <- complex_calculation(10, 5, 3)</span> <span class="token comment"># In debug mode, you can examine variables and step through code</span> |
Using debug() and debugonce()
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<span class="token comment"># Function to debug</span> troublesome_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> y <span class="token operator"><-</span> x <span class="token operator">*</span> <span class="token number">2</span> z <span class="token operator"><-</span> y <span class="token operator">+</span> <span class="token number">10</span> w <span class="token operator"><-</span> z <span class="token operator">/</span> x return<span class="token punctuation">(</span>w<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Set debug mode</span> <span class="token comment"># debug(troublesome_function)</span> <span class="token comment"># Run - will enter debug mode</span> <span class="token comment"># troublesome_function(5)</span> <span class="token comment"># Debug just once</span> <span class="token comment"># debugonce(troublesome_function)</span> <span class="token comment"># Turn off debugging</span> <span class="token comment"># undebug(troublesome_function)</span> |
Adding Trace Information
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<span class="token comment"># Function with trace output</span> calculate_with_trace <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> verbose <span class="token operator">=</span> <span class="token boolean">FALSE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Step 1: Input x ="</span><span class="token punctuation">,</span> x<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> y <span class="token operator"><-</span> x<span class="token operator">^</span><span class="token number">2</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Step 2: Squared y ="</span><span class="token punctuation">,</span> y<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> z <span class="token operator"><-</span> log<span class="token punctuation">(</span>y <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Step 3: Log z ="</span><span class="token punctuation">,</span> z<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> exp<span class="token punctuation">(</span>z<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Step 4: Final result ="</span><span class="token punctuation">,</span> result<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token comment"># Verify result (should equal x^2)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Verification: Should equal x^2 ="</span><span class="token punctuation">,</span> x<span class="token operator">^</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Run with and without tracing</span> print<span class="token punctuation">(</span>calculate_with_trace<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> verbose <span class="token operator">=</span> <span class="token boolean">FALSE</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>calculate_with_trace<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> verbose <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Part 12: Best Practices
1. Use Descriptive Names
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment"># ❌ Bad</span> f <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>a <span class="token operator">*</span> b <span class="token operator">/</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Good</span> calculate_percentage <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>part<span class="token punctuation">,</span> whole<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span><span class="token punctuation">(</span>part <span class="token operator">/</span> whole<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
2. Keep Functions Small and Focused
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<span class="token comment"># ❌ Too many responsibilities</span> process_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Clean data</span> data <span class="token operator"><-</span> na.omit<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Calculate stats</span> mean_val <span class="token operator"><-</span> mean<span class="token punctuation">(</span>data<span class="token punctuation">)</span> sd_val <span class="token operator"><-</span> sd<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Create plot</span> plot<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Save results</span> write.csv<span class="token punctuation">(</span>data<span class="token punctuation">,</span> <span class="token string">"output.csv"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span>mean <span class="token operator">=</span> mean_val<span class="token punctuation">,</span> sd <span class="token operator">=</span> sd_val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Break into smaller functions</span> clean_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>na.omit<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> calculate_stats <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span>mean <span class="token operator">=</span> mean<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span> sd <span class="token operator">=</span> sd<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> plot_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> plot<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">}</span> save_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> filename<span class="token punctuation">)</span> <span class="token punctuation">{</span> write.csv<span class="token punctuation">(</span>data<span class="token punctuation">,</span> filename<span class="token punctuation">)</span> <span class="token punctuation">}</span> process_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> cleaned <span class="token operator"><-</span> clean_data<span class="token punctuation">(</span>data<span class="token punctuation">)</span> stats <span class="token operator"><-</span> calculate_stats<span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> plot_data<span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> save_data<span class="token punctuation">(</span>cleaned<span class="token punctuation">,</span> <span class="token string">"output.csv"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>stats<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
3. Document Your Functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment">#' Calculate Body Mass Index (BMI)</span> <span class="token comment">#'</span> <span class="token comment">#' This function calculates the Body Mass Index given weight and height.</span> <span class="token comment">#'</span> <span class="token comment">#' @param weight_kg Numeric, weight in kilograms</span> <span class="token comment">#' @param height_m Numeric, height in meters</span> <span class="token comment">#' @param rounded Logical, whether to round result to 1 decimal place</span> <span class="token comment">#'</span> <span class="token comment">#' @return Numeric BMI value</span> <span class="token comment">#' @examples</span> <span class="token comment">#' calculate_bmi(70, 1.75)</span> <span class="token comment">#' calculate_bmi(70, 1.75, rounded = FALSE)</span> <span class="token comment">#'</span> <span class="token comment">#' @export</span> calculate_bmi <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>weight_kg<span class="token punctuation">,</span> height_m<span class="token punctuation">,</span> rounded <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> bmi <span class="token operator"><-</span> weight_kg <span class="token operator">/</span> <span class="token punctuation">(</span>height_m<span class="token operator">^</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>rounded<span class="token punctuation">)</span> <span class="token punctuation">{</span> bmi <span class="token operator"><-</span> round<span class="token punctuation">(</span>bmi<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>bmi<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
4. Validate Inputs
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
robust_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Check existence</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>missing<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">||</span> missing<span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Both x and y must be provided"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Check type</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>is.numeric<span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"x and y must be numeric"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Check length</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">||</span> length<span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"x and y must be single values"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Check range</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>y <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"y cannot be zero"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Function logic</span> return<span class="token punctuation">(</span>x <span class="token operator">/</span> y<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Summary: The Function Philosophy
Functions are your tools for abstraction and reusability. Master these concepts:
-
Definition and calling – Creating and using functions
-
Parameters – Passing data into functions
-
Return values – Getting results out
-
Scope – Understanding variable visibility
-
Error handling – Making functions robust
-
Documentation – Making functions usable by others
Best practices:
-
Give functions clear, descriptive names
-
Keep functions focused on a single task
-
Validate inputs at the beginning
-
Document what the function does
-
Return meaningful results
-
Handle errors gracefully
-
Test your functions thoroughly
When to write a function:
-
You repeat the same code more than twice
-
You need to perform a well-defined task
-
You want to make your code more readable
-
You’re building a reusable tool
-
You need to encapsulate complexity
Functions transform you from a person who writes scripts to a person who builds tools. They’re the difference between cooking a meal once and creating a recipe that can be used forever.
Would you like me to elaborate on any specific aspect of functions or explore more advanced topics like functional programming, closures, or creating packages?
