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
zscorehas 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.datain 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.datalike 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
