【问题标题】:Creating a dynamic Group By创建动态分组依据
【发布时间】:2020-10-09 19:20:36
【问题描述】:
df = data.frame(
  A = c(1, 4, 5, 13, 2),
  B = c("Group 1", "Group 3", "Group 2", "Group 1", "Group 2"),
  C = c("Group 3", "Group 2", "Group 1", "Group 2", "Group 3")
)

df %>%
  group_by(B) %>%
  summarise(val = mean(A))

df %>%
  group_by(C) %>%
  summarise(val = mean(A))

我不想为每个唯一的 group_by 集编写新的代码块,而是想创建一个循环,该循环将遍历 df 数据帧并将结果保存到列表或数据帧中。

我想看看特征 A 的平均值如何在特征 BC 之间传播,而无需编写新的数据集中每个分类特征的代码块。

我试过这个:

List_Of_Groups <- map_df(df, function(i) {
  df %>% 
    group_by(!!!syms(names(df)[1:i])) %>% 
    summarize(newValue = mean(A))
})

【问题讨论】:

    标签: r dataframe dplyr tidyverse purrr


    【解决方案1】:

    使用purrrmap,您可以将您指定的代码块应用于所有字符列。基本上,您将字符变量的名称​​映射到后面的函数

    purrr::map(names(df %>% select(where(is.character))), function(i) {
      df %>% 
        group_by(!!sym(i)) %>% 
        summarize(newValue = mean(A))
    })
    

    输出

    # [[1]]
    # A tibble: 3 x 2
    #   B       newValue
    #   <chr>      <dbl>
    # 1 Group 1      7  
    # 2 Group 2      3.5
    # 3 Group 3      4  
    # 
    # [[2]]
    # A tibble: 3 x 2
    #   C       newValue
    #   <chr>      <dbl>
    # 1 Group 1      5  
    # 2 Group 2      8.5
    # 3 Group 3      1.5
    

    【讨论】:

    • 请原谅这个双关语,但where 来自哪里?包?
    • where 是一个tidyselect 函数,可以在dplyr 1.0.0 版的某些dplyr 语句中使用。可以看一些例子here
    • @Loncar 最好更新它们:) 否则你可以使用names(df %&gt;% select_if(is.character)) 并且结果会一样
    • 你的变量是字符还是因子?你有没有试过如果你写c("B", "C")而不是names(...),它是否有效?
    • 这很奇怪,因为names()应该返回一个列名的字符向量。如果你运行names(df %&gt;% select(where(is.character)))names(df %&gt;% select_if(is.character)),输出是什么?
    【解决方案2】:

    您可以使用 A 作为标识符将其旋转很长,然后按以下方式分组:

    library(tidyr)
    df %>% pivot_longer(-A) %>% group_by(name,value) %>% summarize(val=mean(A))
    # A tibble: 6 x 3
    # Groups:   name [2]
      name  value     val
      <chr> <fct>   <dbl>
    1 B     Group 1   7  
    2 B     Group 2   3.5
    3 B     Group 3   4  
    4 C     Group 1   5  
    5 C     Group 2   8.5
    6 C     Group 3   1.5
    

    【讨论】:

      【解决方案3】:

      你可以试试这样的:

      library(dplyr)
      empty_list <- list(0)
      for(i in 2:dim(df)[2])
      {
        empty_list[[i-1]]<-df %>% group_by(df[,i]) %>% summarise(val = mean(A))
      }
      empty_list
      
      [[1]]
      # A tibble: 3 x 2
        `df[, i]`   val
        <fct>           <dbl>
      1 Group 1           7  
      2 Group 2           3.5
      3 Group 3           4  
      
      [[2]]
      # A tibble: 3 x 2
        `df[, i]`   val
        <fct>           <dbl>
      1 Group 1           5  
      2 Group 2           8.5
      3 Group 3           1.5
      

      希望这能有所帮助。

      【讨论】:

        猜你喜欢
        • 2014-12-09
        • 2012-10-04
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 2011-11-12
        相关资源
        最近更新 更多