【问题标题】:R rbind rows to df with results calculated by group for multiple columns by nameR rbind rows to df 并按名称为多列按组计算结果
【发布时间】:2016-05-31 21:27:09
【问题描述】:

如何按“id”分组,将一些算术函数应用于最后四列(按组),并将新行添加到包含结果的 df。这是一个有 5 个样本 (id) 和 8 列的说明性示例:

    d1   d2   id  type         treat  v1_gm  v2_pct v3_pct
1   info info 1   leaf         NA     0.2    70     90
2   info info 1   flower       A      0.5    80     80
3   info info 2   leaf         NA     0.4    65     80
4   info info 2   flower       A      0.1    90     90
5   info info 3   leaf         NA     0.6    55     80
6   info info 3   stem         A      0.3    80     30
7   info info 4   leaf         NA     0.6    30     40
8   info info 4   flower       A      0.7    75     75
9   info info 5   leaf/stem    NA     0.8    80     75

可重现的例子:

df <- data.frame(matrix(NA, nrow = 9, ncol = 8), row.names=NULL)
colnames(df) <- c("d1","d2","id","type","treat","v1_gm","v2_pct","v3_pct")
df$d1 <- "info"
df$d2 <- "info"
id <- c(1,1,2,2,3,3,4,4,5)
df$id <- c(1,1,2,2,3,3,4,4,5)
df$type <- c("leaf","flower","leaf","flower","leaf","stem","leaf","flower","leaf/stem")
df$treat <- c(NA,"A",NA,"A",NA,"A",NA,"A",NA)
df$v1_gm <- c(0.2,0.5,0.4,0.1,0.6,0.3,0.6,0.7,0.8)
df$v2_pct <- c(70,80,65,90,55,80,30,75,80)
df$v3_pct <- c(90,80,80,90,80,30,40,75,75)

结果表应如下所示。第 3、6、9 和 13 行是包含结果的新行。新行可以附加在表的末尾,或者放入一个 tmp df 以便稍后使用 rbind 添加(无论哪种方式,我都不知道该怎么做)。分组变量是列“id”。函数 sum 用于“v1_gm”。函数“mean”用于多个连续列,此处为“v1_pct”和“v3_pct”,应按名称调用(例如,v1_pct:v3_pct)。新行中“type”的值与组行中的“type”连接,“d1”和“d2”简单地从其中treat=="A"的组行中复制,新行中的“treat”行被赋值为“cmb”。

    d1   d2   id type         treat v1_gm  v2_pct  v3_pct
1   info info 1  leaf         NA    0.2    70      90
2   info info 1  flower       A     0.5    80      80
3   info info 1  leaf/flower  cmb   0.7    75      85
4   info info 2  leaf         NA    0.4    65      80
5   info info 2  flower       A     0.1    90      90
6   info info 2  leaf/flower  cmb   0.5    77.5    85
7   info info 3  leaf         NA    0.6    55      80
8   info info 3  stem         A     0.3    80      30
9   info info 3  leaf/stem    cmb   0.9    67.5    55
10  info info 4  leaf         NA    0.6    30      40
11  info info 4  flower       A     0.7    75      75
13  info info 4  leaf/flower  cmb   1.3    52.5    57.5
14  info info 5  leaf/stem    NA    0.8    80      75

【问题讨论】:

    标签: r dplyr group-summaries


    【解决方案1】:

    我不确定您是否可以将组摘要作为一行添加到数据框中。您应该可以将其作为一个列来完成。

    library("dplyr")
    res1 <- df %>% group_by(id) %>% mutate( sumV1 = sum(v1_gm),meanV2 = mean(v2_pct),meanV3 = mean(v3_pct),gr_type = paste(type,collapse="/")) %>% filter(treat == "A") %>% select(d1,d2,id,type,v1_gm=sumV1, v2_pct = meanV2, v3_pct = meanV3,type = gr_type)
    

    这会给你答案,然后使用 bind_rows 你会得到你想要的结果

    final_res <- bind_rows(df,res1)
    

    【讨论】:

    • 在 str_c(type, sep="/") 中的连接似乎不起作用,但如果可以,我可以将结果发送到时间文件,删除所有处理的行!= “A”,将计算的列重命名为原始列名,并将 tmp 与原始文件进行 rbind。
    • 抱歉,您可以改用粘贴命令。我已对答案进行了更改。然后您可以使用管道命令进行过滤..
    • 实际上,我所拥有的实际数据表还有 25 列类似于 v3_pct 之后的列,所有这些列都需要以与 v2_pct 和 v3_pct 相同的方式处理(即,按组表示)。如果最后一列是 v25,是否有一种方法可以概括您的代码以选择 v1_pct : v25 以避免单独键入每个进行计算?
    【解决方案2】:

    通过对@Arun 的回答进行一些修改,下面的脚本完全解决了这个问题。

    library("dplyr")
    res1 <- df %>%  
      group_by(id) %>%  
      mutate(  
        v1_gm = sum(v1_gm),  
        v2_pct = mean(v2_pct),  
        v3_pct = mean(v3_pct),  
        type = paste(type,collapse="/")) %>%  
      filter(treat == "A") %>%  
      mutate(treat = as.character("calculated"))  
    final_res1 <- bind_rows(df,res1)  
    final_res1$id <- as.character(final_res1$id)  
    final_res1 <- final_res1 [order(final_res1$id, final_res1$treat, na.last=FALSE),  ] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多