Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to gather then mutate a new column then spread to wide format again

Tags:

r

dplyr

tidyr

Using tidyr/dplyr, I have some factor columns which I'd like to Z-score, and then mutate an average Z-score, whilst retaining the original data for reference.

I'd like to avoid using a for loop in tidyr/dplyr, thus I'm gathering my data and performing my calculation (Z-score) on a single column. However, I'm struggling with restoring the wide format.

Here is a MWE:

library(dplyr)
library(tidyr)

# Original Data
dfData <- data.frame(
  Name = c("Steve","Jwan","Ashley"),
  A = c(10,20,12),
  B = c(0.2,0.3,0.5)
) %>% tbl_df() 

# Gather to Z-score
dfLong <- dfData %>% gather("Factor","Value",A:B) %>% 
  mutate(FactorZ = paste0("Z_",Factor)) %>% 
  group_by(Factor) %>% 
  mutate(ValueZ = (Value - mean(Value,na.rm = TRUE))/sd(Value,na.rm = TRUE))

# Now go wide to do some mutations (eg Z)Avg = (Z_A + Z_B)/2)

# This does not work
dfWide <- dfLong %>% 
  spread(Factor,Value) %>%
  spread(FactorZ,ValueZ)%>% 
  mutate(Z_Avg = (Z_A+Z_B)/2)


# This is the desired result
dfDesired <- dfData %>% mutate(Z_A = (A - mean(A,na.rm = TRUE))/sd(A,na.rm = TRUE)) %>% mutate(Z_B = (B - mean(B,na.rm = TRUE))/sd(B,na.rm = TRUE)) %>% 
                    mutate(Z_Avg = (Z_A+Z_B)/2)

Thanks for any help/input!

like image 610
csrvermaak Avatar asked Nov 18 '25 07:11

csrvermaak


2 Answers

Another approach using dplyr (version 0.5.0)

library(dplyr)

dfData  %>% 
   mutate_each(funs(Z = scale(.)), -Name) %>% 
   mutate(Z_Avg = (A_Z+B_Z)/2)
like image 170
Sotos Avatar answered Nov 19 '25 22:11

Sotos


means <-function(x)mean(x, na.rm=T)
dfWide %>% group_by(Name) %>% summarise_each(funs(means)) %>% mutate(Z_Avg = (Z_A + Z_B)/2)

# A tibble: 3 x 6
    Name     A     B        Z_A        Z_B      Z_Avg
   <chr> <dbl> <dbl>      <dbl>      <dbl>      <dbl>
1 Ashley    12   0.5 -0.3779645  1.0910895  0.3565625
2   Jwan    20   0.3  1.1338934 -0.2182179  0.4578378
3  Steve    10   0.2 -0.7559289 -0.8728716 -0.8144003
like image 21
Adam Quek Avatar answered Nov 19 '25 20:11

Adam Quek