繁体   English   中英

如何在R中使用dplyr将数据框中的行与多列配对?

[英]How to pair rows in a data frame with many columns using dplyr in R?

我有一个数据框,其中包含来自对照和实验组的多个观察结果,每个受试者都有重复。

这是我的数据框的示例:

subject  cohort    replicate val1   val2
  A     control       1       10     0.1
  A     control       2       15     0.3
  A     experim       1       40     0.7
  A     experim       2       45     0.9
  B     control       1        5     0.3     
  B     experim       1       30     0.0
  C     control       1       50     0.5
  C     experim       1       NA     1.0

我想将每个对照观察值与对应的实验观察值配对,以计算每个值之间的比率。 所需的输出如下所示:

subject  replicate   ratio_val1   ratio_val2
  A         1           4             7
  A         2           3             3
  B         1           6             0
  C         1          NA             2 

理想情况下,我希望使用dplyr和管道实现此功能。

您可以使用summarize_at功能从dplyr总结列val1val2通过分组数据后, subjectreplicate 使用[cohort == ...]分别提取实验组和对照组的值进行划分:

library(dplyr)
df %>% group_by(subject, replicate) %>% 
       summarize_at(vars(contains('val')), 
                    funs("ratio" = .[cohort == "experim"]/.[cohort == "control"]))

# Source: local data frame [4 x 4]
# Groups: subject [?]
#
#   subject replicate val1_ratio val2_ratio
#    <fctr>     <int>      <dbl>      <dbl>
# 1       A         1          4          7
# 2       A         2          3          3
# 3       B         1          6          0
# 4       C         1         NA          2

我们可以通过将数据集重塑为“宽”格式来使用data.table

library(data.table)
dcast(setDT(df1), subject+replicate~cohort, value.var = c("val1", "val2"))[,
          paste0("ratio_", names(df1)[4:5]) := Map(`/`, .SD[,  
      grep("experim", names(.SD)), with = FALSE], 
       .SD [, grep("control", names(.SD)), with = FALSE])][, (3:6) := NULL][]
#    subject replicate ratio_val1 ratio_val2
# 1:       A         1          4          7
# 2:       A         2          3          3
# 3:       B         1          6          0 
# 4:       C         1         NA          2

或在与“主题”,“复制”分组之后,我们遍历“ val”列,并将“ experim”的“ val”对应元素与“ control”的对应元素分开

setDT(df1)[, lapply(.SD[, grep("val", names(.SD)), with = FALSE], 
   function(x) x[cohort =="experim"]/x[cohort =="control"]) ,
               by = .(subject, replicate)]

或者我们可以使用tidyr gather/spread

library(dplyr)
library(tidyr)
df1 %>%
   gather(Var, Val, val1:val2) %>%
   spread(cohort, Val) %>% 
   group_by(subject, replicate, Var) %>%
   summarise(ratio = experim/control) %>% spread(Var, ratio)
#    subject replicate  val1  val2
#      <chr>     <int> <dbl> <dbl>
# 1       A         1     4     7
# 2       A         2     3     3
# 3       B         1     6     0
# 4       C         1    NA     2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM