【问题标题】:Sum up two variables in a long-format dataframe with tidyverse用 tidyverse 总结长格式数据框中的两个变量
【发布时间】:2019-02-04 17:43:18
【问题描述】:

我有一个格式整洁的简单数据框:

  group variable               value
  <fct> <chr>                  <dbl>
1     fishers_here         100
1     money_per_fisher     2000
1     unnecessary_variable 10
2     fishers_here         140
2     money_per_fisher     8000
2     unnecessary_variable 304
3     fishers_here         10
3     money_per_fisher     9000
....

对于每个组,我希望有变量“组中的总金额”,即 fishers_here * money_per_fisher;基本上我希望它看起来像这样:

  group variable               value
  <fct> <chr>                  <dbl>
1     fishers_here         100
1     money_per_fisher     2000
1     unnecessary_variable 10
1     TOTAL_MONEY          200000

....

有没有一种简单的方法可以用 tidyverse 完成这项工作? 简单来说,我的意思是不必过滤、汇总、添加变量列,然后将两个现在分开的数据框连接起来。

【问题讨论】:

  • 让我改写它以增加清晰度
  • 没有。最简单的方法是总结和合并。除了连接之外,没有任何动词可以添加新行。您也许可以使用do(),但不确定它的推荐程度。
  • 第 6 行是否有错字,应该是第 1 组?还是实际上有重复的行

标签: r dplyr tidyverse


【解决方案1】:

你可以spread,做乘法然后gather备份。请注意,正如我所评论的,我假设第 6 行中的组号有错字,它应该是第 2 组而不是第 1 组。如果不是这种情况,则需要一些额外的清洁步骤。您还可以根据需要对结果行进行排序(例如,将每个组的行重新放在一起)

library(tidyverse)
tbl <- read_table2(
  "group variable               value
  1     fishers_here         100
1     money_per_fisher     2000
1     unnecessary_variable 10
2     fishers_here         140
2     money_per_fisher     8000
2     unnecessary_variable 304
3     fishers_here         10
3     money_per_fisher     9000"
)
tbl %>%
  spread(variable, value) %>%
  mutate(total_money_in_group = money_per_fisher * fishers_here) %>%
  gather(variable, value, -group)
#> # A tibble: 12 x 3
#>    group variable               value
#>    <dbl> <chr>                  <dbl>
#>  1     1 fishers_here             100
#>  2     2 fishers_here             140
#>  3     3 fishers_here              10
#>  4     1 money_per_fisher        2000
#>  5     2 money_per_fisher        8000
#>  6     3 money_per_fisher        9000
#>  7     1 unnecessary_variable      10
#>  8     2 unnecessary_variable     304
#>  9     3 unnecessary_variable      NA
#> 10     1 total_money_in_group  200000
#> 11     2 total_money_in_group 1120000
#> 12     3 total_money_in_group   90000

reprex package (v0.2.1) 于 2019 年 2 月 4 日创建

【讨论】:

    【解决方案2】:

    一个选项是filter 'money_per_fisher'、'fishers_here',按'group'分组,summarise 获取'value'的prod,将行与原始数据和@987654324 绑定@由“组”

    library(tidyverse)
    df1 %>%
       filter(variable %in% c('fishers_here', 'money_per_fisher')) %>%
       group_by(group) %>% 
       summarise(variable = "total_money_in_group", value = prod(value)) %>% 
       bind_rows(tbl, .) %>% 
       arrange(group)
    # A tibble: 11 x 3
    #   group variable               value
    #   <int> <chr>                  <dbl>
    # 1     1 fishers_here             100
    # 2     1 money_per_fisher        2000
    # 3     1 unnecessary_variable      10
    # 4     1 total_money_in_group  200000
    # 5     2 fishers_here             140
    # 6     2 money_per_fisher        8000
    # 7     2 unnecessary_variable     304
    # 8     2 total_money_in_group 1120000
    # 9     3 fishers_here              10
    #10     3 money_per_fisher        9000
    #11     3 total_money_in_group   90000
    

    数据

    df1 <- structure(list(group = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L),
     variable = c("fishers_here", 
     "money_per_fisher", "unnecessary_variable", "fishers_here", "money_per_fisher", 
     "unnecessary_variable", "fishers_here", "money_per_fisher"), 
    value = c(100L, 2000L, 10L, 140L, 8000L, 304L, 10L, 9000L
    )), class = "data.frame", row.names = c(NA, -8L))
    

    【讨论】:

      【解决方案3】:

      根据您的输出,我认为这是一个可能的解决方案:

      df %>% 
         group_by(group) %>% 
         summarise(value = prod(value))
      

      编辑:如果您想在原始数据集中有一列,您可以使用 mutate 而不是 summarise

      【讨论】:

      • 谢谢你;它不会起作用,因为它会乘以不感兴趣的变量。当然我可以先过滤,但我希望避免必须做所有这些工作,然后必须在以后离开两个数据帧。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 2016-08-15
      相关资源
      最近更新 更多