R: How to select subsets of a column and repeat this over several columns

Viewed 86

I have a dataframe with 100 rows and 13 columns. The dataframe contains observation of 11 levels (control, group1, group2, ...)

treatment variable1 variable 2
control 1 3
control 2 4
control 0.5 2
group1 1.2 1.2
group1 3 6
  1. I have to create the effect size of my groups. To do so I need to subset my data into the individual treatments of variable 1. Next, I have to use the subsets in a formula:
cohen.d(var1$group1, var1$control, na.rm = TRUE, hedges = T) %>% .$estimate
  1. This steps have to be repeated to compare 10 different treatments with my control group.
  2. The steps have to be repeated for each column (variable)
  3. I want to store the output of the cohen.d formula in tibble

How to do these steps without having to much code? I tried it like this...

hedge_calc <- function(y){
  
  df <- data_single_response %>% select(c(y,), treatment)
  
  x <- list()
  for (i in 1:length(factor.list)){
    x[i] <- df %>% filter(., remark == factor.list[i])
  }
  
  h <- list()
  for (i in 1:length(factor.list)){
    h[i] <- cohen.d(as.numeric(as.character(unlist(x[[i]]))), as.numeric(as.character(unlist(x[[1]]))) 
                    , na.rm = TRUE, hedges = T) %>% .$estimate
  }
  c <- list()
  for (i in 1:length(factor.list)){
    c[i] <- cohen.d(as.numeric(as.character(unlist(x[[i]]))), as.numeric(as.character(unlist(x[[1]]))) 
                    , na.rm = TRUE, hedges = T) %>% .$conf.int%>% .[1]
  }
  
  d <- list()
  for (i in 1:length(factor.list)){
    d[i] <- cohen.d(as.numeric(as.character(unlist(x[[i]]))), as.numeric(as.character(unlist(x[[1]]))) 
                    , na.rm = TRUE, hedges = T) %>% .$conf.int %>% .[2]
  }


  
  result <- data.frame(hedges_g = unlist(h), lower = unlist(c),
                       upper = unlist(d), treat_vs_control = factor.list[1:11])
  
  print(result)
}

hedge_calc(3)

... and received my results by looping from column 2:13. BUt because this is super confusing to read and error prone, I need to use a better code.

Do you have any ideas??

Many thanks to everyone :)

1 Answers

Let df be as follows

> df
  treatment variable1 variable2
1   control       1.0       3.0
2   control       2.0       4.0
3   control       0.5       2.0
4    group1       1.2       1.2
5    group1       3.0       6.0
6    group2       4.0       6.0
7    group2       5.0       7.0

Then you first split the data.frame according to the different treatment levels and then execute two lapply() statements to iterate both over the variables as well as the groups.

cohen_list <- lapply(2:ncol(df), 
                      function(y) lapply(2:length(df_list), 
                                    function(x) cohen.d(df_list[[1]][, y],  
                                                        df_list[[x]][, y], 
                                                        na.rm = TRUE, hedges= TRUE)$estimate))

Then you bind the lists together, transpose it into a useful format and convert it to a dataframe.

final_df <- cohen_list %>% 
            do.call("rbind", .) %>% 
            t %>% 
            as.data.frame

Finally, you adjust the row and column names with

rownames(final_df) <- setdiff(unique(df$treatment), "control")
colnames(final_df) <- colnames(df[,2:ncol(df)])

with the final output

> final_df
        variable1  variable2
group1 -0.7042911 -0.2055516
group2  -3.252463  -2.788406
Related