【问题标题】:For-loop to summarize and joining by dplyr由 dplyr 总结和加入的 for 循环
【发布时间】:2020-02-11 04:01:04
【问题描述】:

这是我的简化df:

GP_A <- c(rep("a",3),rep("b",2),rep("c",2))
GP_B <- c(rep("d",2),rep("e",4),rep("f",1))
GENDER <- c(rep("M",4),rep("F",3))
LOC <- c(rep("HK",2),rep("UK",3),rep("JP",2))
SCORE <- c(50,70,80,20,30,80,90)
df <- as.data.frame(cbind(GP_A,GP_B,GENDER,LOC,SCORE))

> df

GP_A GP_B GENDER LOC SCORE
1    a    d      M  HK    50
2    a    d      M  HK    70
3    a    e      M  UK    80
4    b    e      M  UK    20
5    b    e      F  UK    30
6    c    e      F  JP    80
7    c    f      F  JP    90

我想按 GP_A、GP_B 或本示例中未显示的其他分组列来汇总分数。由于分组列数可能高达 50,因此我决定使用 for-loop 来汇总分数。

原来的方法是用1组一个一个的总结分数:

GP_A_SCORE <- df %>% group_by(GP_A,GENDER,LOC) %>% summarize(SCORE=mean(SCORE))
GP_B_SCORE <- df %>% group_by(GP_B,GENDER,LOC) %>% summarize(SCORE=mean(SCORE))
...

我想要的是使用这样的 for 循环(无法运行):

GP_list <- c("GP_A","GP_B",...)
LOC_list <- c("HK","UK","JP",...)
SCORE <- list()
for (i in GP_list){
    for (j in LOC_list){
SCORE[[paste0(i,j)]] <- df %>% group_by(i,j,GENDER) %>% summarize(SCORE=mean(SCORE))
}}

和“group_by()”一样,变量被分类为字符,这里显示错误:

错误:IJ 列未知

有什么方法可以强制R识别变量吗?

我在 dplyr 的 left_join 上遇到了同样的问题。

当我在循环中执行以下操作时显示错误:left_join(x,y,by=c(i=i))

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你可以得到长格式的数据,然后计算mean

    library(dplyr)
    library(tidyr)
    
    df %>%
      pivot_longer(cols = starts_with('GP')) %>%
      group_by(GENDER ,LOC, name, value) %>%
      summarise(SCORE = mean(SCORE))
    
    #   GENDER LOC   name  value SCORE
    #   <fct>  <fct> <chr> <fct> <dbl>
    # 1 F      JP    GP_A  c        85
    # 2 F      JP    GP_B  e        80
    # 3 F      JP    GP_B  f        90
    # 4 F      UK    GP_A  b        30
    # 5 F      UK    GP_B  e        30
    # 6 M      HK    GP_A  a        60
    # 7 M      HK    GP_B  d        60
    # 8 M      UK    GP_A  a        80
    # 9 M      UK    GP_A  b        20
    #10 M      UK    GP_B  e        50
    

    【讨论】:

      【解决方案2】:

      我们可以从data.table使用melt

      library(data.table)
      melt(setDT(df), measure = patterns("^GP"))[, .(SCORE = mean(SCORE)),
            .(GENDER, LOC, variable, value)]
      

      数据

      df <- data.frame(GP_A,GP_B,GENDER,LOC,SCORE)
      

      【讨论】:

        猜你喜欢
        • 2020-02-28
        • 1970-01-01
        • 1970-01-01
        • 2015-11-26
        • 2021-08-05
        • 1970-01-01
        • 2023-01-25
        • 2016-10-15
        • 2021-09-12
        相关资源
        最近更新 更多