Home > Mobile >  How do I write my own function to create a z-score in R
How do I write my own function to create a z-score in R

Time:10-21

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:

  1. Your function zscore has 4 arguments (x, mean_x, sd_x, and zscore_x) but you only use one of them (x). My first recommendation is to only have that one argument, like so:

    zscore <- function(x) {...}
    
  2. 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)
    }  
    
  3. 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 to test.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
  • Related