-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchapter2.Rmd
774 lines (510 loc) · 24.2 KB
/
chapter2.Rmd
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
---
title : Getting hooked on R
description : Get your brackets ready and deepen your R skills.
--- type:NormalExercise lang:r xp:100 skills:1, 3 key:8d3c2b3c6c
## Generic functions
Welcome to part 2 of **R Short and Sweet**: Getting hooked on R.
Some functions in R are very generic. They can take different objects as their first argument and they seem to magically do exactly what you'd hope they do in all situations.
One such example is the `summary()` function. Depending on the type of data object it receives as it's first argument, `summary()` will produce different convenient results.
*** =instructions
- Execute the code that creates a summary of `sukup` (gender). What does it show you?
- Execute the code that creates a summary of `ika` (age). What does it show you?
- Create a summary of `pituus` (height) in `students2014`.
- Create a summary of the object `students2014`.
*** =hint
- Use the `$` -sign to access `pituus` in `students2014`.
*** =pre_exercise_code
```{r}
# load data from web
students2014 <- read.table("http://www.helsinki.fi/~kvehkala/JYTmooc/JYTOPKYS-data.txt", sep="\t", header=TRUE)
# keep a couple background variables
students2014 <- students2014[,c("sukup","toita","ika","pituus","kenka","kone")]
# recode kone variables missing values as factor levels
students2014$kone <- addNA(students2014$kone)
# keep only rows without missing values
students2014 <- students2014[complete.cases(students2014),]
# integers to numeric
students2014$ika <- as.numeric(students2014$ika)
students2014$pituus <- as.numeric(students2014$pituus)
students2014$kenka <- as.numeric(students2014$kenka)
```
*** =sample_code
```{r}
# students2014 is available
# Create a summary of a factor
summary(students2014$sukup)
# Create a summary of a numeric
summary(students2014$ika)
# Create a summary of 'pituus' in 'students2014'
# Create a summary of the data.frame 'students2014'
```
*** =solution
```{r}
# Create a summary of a factor object
summary(students2014$sukup)
# Create a summary of a numeric object
summary(students2014$ika)
# Create a summary of 'pituus' in 'students2014'
summary(students2014$pituus)
# Create a summary of the data.frame 'students2014'
summary(students2014)
```
*** =sct
```{r}
test_output_contains("summary(students2014$pituus)", incorrect_msg = "Please call summary() on the numeric object students2014$pituus.")
test_output_contains("summary(students2014)", incorrect_msg="Please call summary() on the data.frame object `students2014`")
test_error()
success_msg("Well done!")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:7fa7ad358b
## Help() !
There are many functions in R. It is often hard to remember all the argument names and details of the functions. Luckily, every single function has a help page. Using the help pages is part of using R.
The help page of a function called *func* can be opened by two methods: `help(func)` or `?func`.
*** =instructions
- Create objects `shoesize` and `height`
- Open the help page of `plot` by writing `?plot` directly to the console and press enter.
- Use `plot()` to draw a (scatter) plot of student shoesize versus height, with shoesize on the x axis and height on the y axis.
- Use the information on the help page and add this main title to the plot: "Scatter plot of student shoesize versus height".
*** =hint
- Please note that the tests are sensitive to capital letters and missing spaces etc.
- If you need examples, you can do an internet search for "scatter plot r"
*** =pre_exercise_code
```{r}
# load data from web
students2014 <- read.table("http://www.helsinki.fi/~kvehkala/JYTmooc/JYTOPKYS-data.txt", sep="\t", header=TRUE)
# keep a couple background variables
students2014 <- students2014[,c("sukup","toita","ika","pituus","kenka","kone")]
# recode kone variables missing values as factor levels
students2014$kone <- addNA(students2014$kone)
# keep only rows without missing values
students2014 <- students2014[complete.cases(students2014),]
# integers to numeric
students2014$ika <- as.numeric(students2014$ika)
students2014$pituus <- as.numeric(students2014$pituus)
students2014$kenka <- as.numeric(students2014$kenka)
```
*** =sample_code
```{r}
# Create objects shoesize and height
shoesize <- students2014$kenka
height <- students2014$pituus
# Draw a scatter plot of shoesize and height
```
*** =solution
```{r}
# Create objects shoesize and height
shoesize <- students2014$kenka
height <- students2014$pituus
# Draw a scatter plot of shoesize and height
plot(shoesize, height, main = "Scatter plot of student shoesize versus height")
```
*** =sct
```{r}
test_function("plot",args = c("x","y","main"))
test_error()
success_msg("Very good work!")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:cdc8167255
## Indices and brackets
Vectors in R store multiple values of the same data type. The values in vectors have indices: the first value in a vector has a index `1`, the second value `2` and so on.
You can set or get a single value from a vector by using indices and brackets `[ ]`. Using an index number inside the brackets gives access to a single value from the vector. Using a vector of indices gives access to multiple values (another vector).
It is also possible to rearrange the values in a vector by using indices. Look at the example code to see how indices work.
*** =instructions
- Create the `names` vector.
- See how the indices work by executing the example lines.
- Use brackets and indices on `names` to create a new vector `girls` with values "Liisa" and "Anna" (in that order).
- Use brackets and indices on `names` to create a new vector `boys` with values "Pekka" and "Heikki" (in that order).
*** =hint
- Note that space between the vector object and bracets produces an error.
- Index vectors `c(1,2)` and `c(2,1)` do not produce the same outcome. The order of the values is different.
*** =pre_exercise_code
```{r}
```
*** =sample_code
```{r}
# Let's create a vector
names <- c("Matti", "Pekka", "Liisa", "Anna")
# Acess the first value of the vector
names[1]
# Change the first value of the vector
names[1] <- "Heikki"
# Acess the 1. and 3. value of the vector
names[c(1, 3)]
# Use indices and brackets to separate the names vector into two vectors of the specified ordering
girls <-
boys <-
```
*** =solution
```{r}
# Let's create a vector
names <- c("Matti", "Pekka", "Liisa", "Anna")
# Acess the first value of the vector
names[1]
# Change the first value of the vector
names[1] <- "Heikki"
# Acess the 1. and 3. value of the vector
names[c(1, 3)]
# Use indices and brackets to separate the names vector into two vectors of the specified ordering
girls <- names[c(3, 4)]
boys <- names[c(2, 1)]
```
*** =sct
```{r}
test_object("girls", incorrect_msg = "Did you create `girls`?")
test_object("boys", incorrect_msg = "Did you create `boys`? Are the values in the correct order?")
test_error()
# Final message the student will see upon completing the exercise
success_msg("Such indices. Wow. Much intelligent.")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:fd9977b86d
## Easy vectors
Sometimes you need a very long index vector. In that case it would be a lot of work to create the vector by combining integer values with `c()`. Luckily, there are convenient ways to create long vectors in R.
For integer values, a specially useful one is the method `start:end`, which creates an integer vector with all the values from start to end. The following two lines hence produce identical results
```
1:5
c(1,2,3,4,5)
```
*** =instructions
- Create an integer vector with values from 1 to 5.
- Create an integer vector with even values from 2 to 10.
- Create object `attitude` and give the values in it names matching the indices.
- Access index values 1-5 of `attitude`
- Use `:` to create an integer vector with the values 1, 2, ..., 10
- Access every second value of the `attitude` vector, starting from the 2. value until the 20th value. These values correspond to the even numbered indeces of the vector: 2, 4, .. , 20
*** =hint
- First you will need an index vector with values 2, 4, .. , 20. The example shows how to create such a vector
- You can then use the index vector together with brackets (`[ ]`) to complete the task
*** =pre_exercise_code
```{r}
learning2014 <- read.table("http://www.helsinki.fi/~kvehkala/JYTmooc/learning2014.txt", sep = "\t", header = TRUE)
```
*** =sample_code
```{r}
# learning2014 is available
# Create an integer vector with values 1,2,..,5
1:5
# Create an integer vector with even values 2, 4, .. , 10
(1:5)*2
# Create object attitude and give the data points names 1, 2, ..
attitude <- learning2014$attitude
names(attitude) <- 1:length(attitude)
# Access the values 5 - 10 of attitude
attitude[5:10]
# Create an integer vector with values 1,2,..,10
# Access every second value of attitude from 2. to the 20th index
```
*** =solution
```{r}
# learning2014 is available
# Create an integer vector with values 1,2,..,5
1:5
# Create an integer vector with even values
(1:5)*2
# Create object attitude and give the data points names 1, 2, ..
attitude <- learning2014$attitude
names(attitude) <- 1:length(attitude)
# Access the values 5 - 10 of attitude
attitude[5:10]
# Create an integer vector with values 1,2,..,10
1:10
# Access every second value of attitude from 2. to the 20th index
attitude[(1:10)*2]
```
*** =sct
```{r}
# submission correctness tests
test_student_typed("1:10", not_typed_msg = "Did you use `:` to create and print out the specified integer vector?")
test_output_contains("attitude[(1:10)*2]")
# test if the students code produces an error
test_error()
# Final message the student will see upon completing the exercise
success_msg("Great work!")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:dd36a10fa0
## Logical comparison
Logical conditions are generally important in programming tasks. In R, logical comparison creates logical vectors, which can be used for example to select subsets of data. The logical comparison operators in R are:
operator | description
----------|------------
`==` | exactly equal to
`!=` | not equal to
`<` | less than
`>` | greater than
`<=` | less or equal to
`>=` | greater or equal to
Follow the instructions below to complete the exercise. Take your time.
*** =instructions
- Execute and study the example codes
- Add to the row with `c("a","b","c")`: select a suitable logical comparison operator and a suitable comparison value to produce a result vector `FALSE, FALSE, TRUE`
- Add to the row with `c(1,3,2)`: select a suitable logical comparison operator and a suitable comparison value to produce a result vector `TRUE, FALSE, TRUE`
- Bonus: can you think of other ways of achieving the same results?
*** =hint
- The third example should point you in the right direction
- If you're uncertain, just choose a comparison value and try out a bunch of different operators to figure out what might work.
*** =pre_exercise_code
```{r}
# no pec
```
*** =sample_code
```{r}
# In the comments below: T = TRUE, F = FALSE
# (R also understands these abbreviations)
# Exactly equal
5 == 5 # TRUE
# Not equal
"cat" != "dog" # TRUE
# Greater or equal 3 times
c(0,1,2) >= 1 # F, T, T
# Use logical comparison to produce a result F, F, T
c("a","b","c")
# Use logical comparison to produce a result T, F, T
c(1, 3, 2)
```
*** =solution
```{r}
# In the comments below: T = TRUE, F = FALSE
# (R also understands these abbreviations)
# Exactly equal
5 == 5 # TRUE
# Not equal
"cat" != "dog" # -> TRUE
# Greater or equal 3 times
c(0,1,2) >= 1 # F,T,T
# Use logical comparison to produce a result F,F,T
c("a","b","c") == "c"
# Use logical comparison to produce a result T,F,T
c(1,3,2) < 3
```
*** =sct
```{r}
# submission correctness tests
# example tests:
test_output_contains("c('a','b','c')=='c'", incorrect_msg = "Please make the necessary adustments to produce the output FALSE FALSE TRUE")
test_output_contains("c(1,3,2)<3", incorrect_msg = "Please make the necessary adustments to produce the output TRUE FALSE TRUE")
# test if the students code produces an error
test_error()
# Final message the student will see upon completing the exercise
success_msg("Well done! Logic is the beginning of wisdom, not the end. - Spock")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:2eebe0d715
## Logical operators
Logical conditions can be combined with the following logical operators:
operator | description
----------------------- | -----------
`!`a | NOT a
a `&` b | a AND b
a <code>|</code> b | a OR b
Logical operators work like logical conditions: they compare the elements of vectors one at a time and can produce logical vectors.
So, for example `F & T` evaluates to `FALSE` and `F | T` evaluates to `TRUE`. Also, `c(F, T) & c(T, T)` produces a logical vector `FALSE TRUE`.
It is also possible to use parenthesis to control the evaluation of the operators. See how this works from the example codes.
*** =instructions
- Create and print out four subsets of the learning2014 data matching the following conditions. Use the `subset()` function.
- (gender is male, "M") AND (deep learning is greater than 4.5)
- (age is 25 OR age is 26) AND (attitude is greater than 3.5)
- (gender is female, "N") AND (strategic learning is greater than 4.5)
- (deep learning is more than 4) AND (points is zero OR points is greater than 30)
*** =hint
- The instructions show the correct use of parenthesis when using the logical operators and conditions
- Note that females are coded with "N", not "F".
- Note that the logical equals is `==`, not `=`.
*** =pre_exercise_code
```{r}
learning2014 <- read.table("http://www.helsinki.fi/~kvehkala/JYTmooc/learning2014.txt", sep = "\t", header = TRUE)
```
*** =sample_code
```{r}
# learning2014 is available
# male students who scored very high on deep learning
subset(learning2014, (gender == "M") & (deep > 4.5))
# 25 or 26 old students who scored high on attitude
subset(learning2014, (age == 25 | age == 26) & (attitude > 3.5))
# female students who scored very high on strategic learning
# students who scored high on deep learning for whom points is 0 or greater than 30
```
*** =solution
```{r}
# learning2014 is available
# male students who scored very high on deep learning
subset(learning2014, (gender == "M") & (deep > 4.5))
# 25 or 26 old students who scored high on attitude
subset(learning2014, (age == 25 | age == 26) & (attitude > 3.5))
# female students who scored very high on strategic learning
subset(learning2014, (gender == "N") & (stra > 4.5))
# students who scored high on deep learning for whom points is 0 or greater than 30
subset(learning2014, deep > 4 & (points == 0 | points > 30))
```
*** =sct
```{r}
# submission correctness tests
test_output_contains("subset(learning2014,(gender=='N')&(stra>4.5))", incorrect_msg="Please print out the subset containing the female students with high strategic learning scores")
test_output_contains("subset(learning2014,deep>4&(points==0|points>30))", incorrect_msg="Please print out the subset containing the students who scored high on deep learning and had either no points or very high points")
# test if the students code produces an error
test_error()
# Final message the student will see upon completing the exercise
success_msg("Excellent! You are the operator indeed.")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:5935ba749b
## Looping
In programming, often there is the need to repeat an action multiple times. In statistical programming you might for example have a theory you wish to explore by simulation.
The **for-loop** is perhaps the most common loop in programming. The structure of a for-loop is:
```
for (counter in vector) {
commands
more commands
}
```
The for-loop iterates trough the values of a vector by changing the value of the counter one at a time. The counter first takes on the first value of the vector, then the second and so on.
Inside the curly braces is the *body* of the loop, which can contain regular commands such as function calls. The current value of the counter can be used there. All the commands inside the body are repeated until the counter has taken all the values of the vector.
*** =instructions
- **Please note!** Here in DataCamp, executing a command over multiple lines is done by selecting (painting) the lines with a mouse first and then hitting `Ctrl+Enter` normally. Alternatively you could also click submit to execute the whole script.R
- Loop though the character values using the example code.
- Loop through integer values using the example code.
- In an honor of the legendary electronic duo *Daft Punk* and their 2001 album *Discovery*, construct a for-loop that prints out "One more time!" 27 times.
- Hints: (1) Remember that `1:n` creates an integer vector of length n. (2) Inside the loop body you have to use the `print()` function to print.
*** =hint
- It does not matter what name you give to your counter. You can for example use `i` as is done in the second example.
- In this exercise you don't need to use the values of your counter.
- Remember to use quotation marks to print characters.
*** =pre_exercise_code
```{r}
# no pec
```
*** =sample_code
```{r}
# Loop through and print the characters a, b, c, d
for(letter in c("a","b","c","d")) {
print(letter)
}
# Loop through integers 1, 2, 3, 4, 5
for(i in 1:5) {
print(i + 5)
}
# Write a for-loop that prints out "One more time!" 27 times
```
*** =solution
```{r}
# loop through characters a,b,c,d
for(letter in c("a","b","c","d")) {
print(letter)
}
# loop through integers 1, 2, 3, 4, 5
for(i in 1:5) {
print(i + 5)
}
# Write a for-loop that prints out "One more time!" 27 times
for(i in 1:27) {
print("One more time!")
}
```
*** =sct
```{r}
# submission correctness tests
test_output_contains("'One more time!'", times = 27, incorrect_msg = "Did you write a for-loop that prints out 'One more time!' 27 times?")
# test if the students code produces an error
test_error()
# Final message the student will see upon completing the exercise
success_msg("Excellent work! Repetition is the key to success :)")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:ca4352832b
## Packages in R
There are a lot of functions in R. But actually, the functions in R come from a standard set of *packages*. A package is simply a collection of R functions. Besides the basic packages, you can install and use (or develop!) other packages too.
You can install packages through CRAN (The Comprehensive R Archive Network). From the CRAN website [https://cran.r-project.org/](https://cran.r-project.org/):
> CRAN is a network of ftp and web servers around the world that store identical, up-to-date, versions of code and documentation for R.
List of available CRAN packages can be seen [here](https://cran.r-project.org/web/packages/available_packages_by_name.html). There are thousands of them, made by R users around the world. In order to get a package accepted to CRAN, the package must be well documented: every function must have a help page.
If you have R in your own computer, you can install packages by calling `install.packages("name_of_the_package")`. Here in DataCamp, most useful packages are already installed for you.
To use installed packages, you need to access them. This is done by calling `library(name_of_the_package)`.
*** =instructions
- One of the most famous and used packages outside the basic R is `ggplot2`. The `ggplot2` packages is a plotting system for R, and it draws pretty pictures for you with small effort.
- The `ggplot2` package has a website [http://ggplot2.org/](http://ggplot2.org/) where you can see documentation about the package.
- Execute the access code for `ggplot2`.
- Draw a plot of gender and points. The `fill` argument adds a legend to the plot.
- Create the `grades` object.
- Do a plot of `grades` and `attitude`. Set `grades` as a legend.
*** =hint
- Copy the code of the `qplot()` function. and change `gender` to `grades` and `points` to `attitude`. Remember to change the `fill` argument also.
*** =pre_exercise_code
```{r}
learning2014 <- read.table("http://www.helsinki.fi/~kvehkala/JYTmooc/learning2014.txt", sep = "\t", header = TRUE)
```
*** =sample_code
```{r}
# learning2014 is available
# Access ggplot2
library(ggplot2)
# Draw a plot of gender and points
qplot(gender, points, data=learning2014, geom="boxplot", fill=gender)
# Create the grades factor
grades <- cut(learning2014$points, breaks = c(0, 11, 15, 19, 23, 27, 33), include.lowest = TRUE)
# Draw a plot of grades and attitude
```
*** =solution
```{r}
#learning2014 is available
# Access ggplot2
library(ggplot2)
# Draw a plot of gender and points
qplot(gender, points, data=learning2014, geom="boxplot", fill=gender)
# Create the grades factor
grades <- cut(learning2014$points, breaks = c(0, 11, 15, 19, 23, 27, 33), include.lowest = TRUE)
# Draw a plot of grades and attitude
qplot(grades, attitude, data=learning2014, geom="boxplot", fill=grades)
```
*** =sct
```{r}
# test_function("qplot", args=c("x", "y", "fill"), incorrect_msg = "Did you draw a plot of `grades` and `attitude`?")
test_error()
# Final message the student will see upon completing the exercise
success_msg("You have the keys do anything. Awesome!")
```
--- type:NormalExercise lang:r xp:100 skills:1 key:270eda4b95
## Create your own functions
There are countless ready-made functions in R. You have already used many functions, such as `str()`, `summary()`, `head()`, `plot()` and `mean()`. But it is possible to create your own functions too. Now we will look at the definition of a simple function and learn how to use it (*call* it).
First a little recap on using functions:
Functions usually have one or more arguments, for which the user can define values when calling the function. Multiple arguments are separated with a comma. The arguments have names, which can (and often should) be used when calling the function.
*** =instructions
- Look at the definition of the `apple_count()` function and execute the function call that is defined.
- Create object `my_apples` by directly assigning the output of `apple_count()` to it. Call `apple_count()` with `new_apples = 10` and `apples_stock = 2`.
- Print `my_apples` to see the output of the function.
- Some of the apples are gone bad! Worms! Create a function `good_apples_count` that takes two arguments: `apples` and `bad_apples`. The function should return the number of apples you have left after the count is **reduced** by an amout set by `bad_apples` (due to a worm attack). Set the number of bad apples to 4 by default.
- Call your ` good_apples_count()` function on `my_apples` to find out how many good apples you have left.
*** =hint
- The answer for `my_apples` is of the form: `my_apples <- apple_count(arg1 = ?, arg2 = ?)`
- See how a new function is created by looking the code of `apple_count`.
- The amount of good apples is `apples` - `bad_apples`.
- You can set the default value: `function(arg1, arg2 = *insert_default_value_here*) ...`
*** =pre_exercise_code
```{r}
apple_count <- function(new_apples, apples_stock = 5) return(new_apples + apples_stock)
```
*** =sample_code
```{r}
# Create a simple function with two arguments, of which 'apples_stock' has a default value 5
apple_count <- function(new_apples, apples_stock = 5) return(new_apples + apples_stock)
# Call the apple_count() function. Can you guess the result?
apple_count(new_apples = 2)
# Call apple_count() to create the object 'my_apples'. Print the results.
my_apples <-
# New function here!
good_apples_count <-
# How many good apples do you have?
```
*** =solution
```{r}
# Create a simple function with two arguments, of which 'apples_stock' has a default value (5)
apple_count <- function(new_apples, apples_stock = 5) return(new_apples + apples_stock)
# Call the apple_count() function. Can you guess the result?
apple_count(new_apples = 2)
# Call apple_count() to create the object 'my_apples'. Print the results.
my_apples <- apple_count(10, apples_stock = 2)
my_apples
# New function here!
good_apples_count <- function(apples, bad_apples = 4) return(apples - bad_apples)
# How many good apples do you have?
good_apples_count(my_apples)
```
*** =sct
```{r}
test_object("my_apples", incorrect_msg ="Did you save results of `apple_count()` to `my_apple`?")
test_output_contains(" good_apples_count(my_apples)", incorrect_msg ="Did you use `good_apples_count()` to `my_apples`?")
test_error()
success_msg("Not eating worms tonight! Nicely done!")
```