I am practicing writing my own functions. I tried to create for function for creating z-scores
age <- c(25, 30, 28, 40, 50)
bmi <- c(22, 24, 30, 26, 35)
test.data <- cbind.data.frame(age, bmi)
zscore <- function(x, mean_x, sd_x, zscore_x) {
test.data <- test.data %>%
mutate(mean_x = mean(x, na.rm = T),
sd_x = sd(x, na.rm = T),
zscore_x = (x - mean_x) / sd_x)
}
zscore(x = bmi,
mean_x = mean_bmi,
sd_x = sd_bmi,
zscore_x = zscore_bmi)
I was hope to create a new variable called zscore_bmi that is added to the test.data, but the new variable is not created. Any suggestions?
CodePudding user response:
Three comments:
Your function
zscore
has 4 arguments (x
,mean_x
,sd_x
, andzscore_x
) but you only use one of them (x
). My first recommendation is to only have that one argument, like so:zscore <- function(x) {...}
The next issue is what to put in the body of the function. Here, we just need the simple z-score calculation:
zscore <- function(x) { (x - mean(x, na.rm=T) ) / sd(x, na.rm=T) }
You should not put
test.data
in the body of the function because it is not an argument to the function. It would be much better to just calculate and return the z-score of your argument. You can then assign that z-score as a new column totest.data
like so:test.data$zscore_myvar <- zscore(myvar)
Putting this all together, here's what you want:
zscore <- function(x) {
(x - mean(x, na.rm=T) ) / sd(x, na.rm=T)
}
test.data$zscore_bmi <- zscore(bmi)
Note that the R function scale
does the same thing and can be used to check your work:
scale(bmi)
## 1.0431010 -0.6567673 0.5022338 -0.2704336 1.4680681
CodePudding user response:
If you want to set name in dplyr
if it's version >= 1.0
, use "{{...}}" :=
.
zscore <- function(x, mean_x, sd_x, zscore_x) {
test.data %>%
dplyr::mutate("{{mean_x}}" := mean(x, na.rm = T),
"{{sd_x}}" := sd(x, na.rm = T),
"{{zscore_x}}" := (x - {{mean_x}}) / {{sd_x}})
}
zscore(x = bmi,
mean_x = mean_bmi,
sd_x = sd_bmi,
zscore_x = zscore_bmi)
age bmi mean_bmi sd_bmi zscore_bmi
1 25 22 27.4 5.176872 -1.0431010
2 30 24 27.4 5.176872 -0.6567673
3 28 30 27.4 5.176872 0.5022338
4 40 26 27.4 5.176872 -0.2704336
5 50 35 27.4 5.176872 1.4680681