【问题标题】:R: dplyr summarize, sum only values of uniquesR:dplyr 总结,仅求和唯一值
【发布时间】:2015-08-20 12:12:02
【问题描述】:

我在使用一个讨厌的命令来分析摘要时遇到问题,为此我使用了dplyr 包。用一些示例数据最容易解释:

structure(list(Date = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L), 
    Name = structure(c(3L, 3L, 4L, 3L, 2L, 3L, 2L, 4L, 1L), .Label = c("George", 
    "Jack", "John", "Mary"), class = "factor"), Birth.Year = c(1995L, 
    1995L, 1997L, 1995L, 1999L, 1995L, 1999L, 1997L, 1997L), 
    Special_Balance = c(10L, 40L, 30L, 5L, 10L, 15L, 2L, 1L, 
    100L), Total_Balance = c(100L, 100L, 50L, 200L, 20L, 200L, 
    20L, 100L, 1600L)), .Names = c("Date", "Name", "Birth.Year", 
"Special_Balance", "Total_Balance"), class = "data.frame", row.names = c(NA, 
-9L))

两个简单的总结是我的目标:首先,我想通过Date 进行总结,代码如下所示。错误的部分是total_balance_sum 计算,我想对每个人的余额求和,但每个人只计算一次。例如,我对Date=1 的命令的结果是total_balance_sum=100,但它应该是150(将Jack 的total_balance 100 一次添加到50 的Mary 的total_balance 一次)。这个错误的计算显然弄乱了最终的pct calc。

example_data %>% 
  group_by(Date) %>% 
  summarise(
    total_people=n_distinct(Name),
    total_loan_exposures=n(),

    special_sum=sum(Special_Balance,na.rm=TRUE),
    total_balance_sum=sum(Total_Balance[n_distinct(Name)]), 
    total_pct=special_sum/total_balance_sum

  ) -> example_summary

在第二个摘要(如下)中,我按日期和出生年份分组,再次错误地计算 total_balance_sum

example_data %>% 
  group_by(Date,Birth.Year) %>% 
  summarise(
    total_people=n_distinct(Name),
    total_loan_exposures=n(),

    special_sum=sum(Special_Balance,na.rm=TRUE),
    total_balance_sum=sum(Total_Balance[n_distinct(Name)]), 
    total_pct=special_sum/total_balance_sum

  ) -> example_summary_birthyear

实现目标的正确方法是什么?显然,我正在使用的 n_distinct 只取其中一个值,而不是在名称之间正确地求和。

感谢您的帮助。

【问题讨论】:

  • 你也能显示你想要的输出吗?

标签: r unique dplyr summary


【解决方案1】:

我有点不清楚您可能要求什么,但这是否符合您的要求?:(仅用于第一个示例)

example_data %>% 
  group_by(Date, Name) %>% 
    summarise(
      total_loan_exposures=n(),
      total_SpecialPerson=sum(Special_Balance,na.rm=TRUE),
      total_balance_sumPerson=Total_Balance[1])%>% 
  ungroup() %>% 
  group_by(Date) %>% 
  summarise(
    total_people=n(),
    total_loan_exposures=sum(total_loan_exposures),
    special_sum=sum(total_SpecialPerson,na.rm=TRUE),
    total_balance_sum=sum(total_balance_sumPerson)) %>% 
  mutate(total_pct=(special_sum/total_balance_sum))-> example_summary

> example_summary
Source: local data frame [3 x 6]

    Date total_people total_loan_exposures special_sum total_balance_sum  total_pct
    1    1            2                    3          80               150 0.53333333
    2    2            2                    4          32               220 0.14545455
    3    3            2                    2         101              1700 0.05941176

【讨论】:

  • 感谢您的帮助。不幸的是,它没有。此处日期 1 的总余额为 250(取约翰两次和玛丽一次之和)。但是,我希望总余额等于 150 - 换句话说,我只想计算一次 John 的总数(即使他有 2 个特殊余额)。所以日期 1 的 total_balance_sum 为 150,日期 2 为 220(约翰:200 + 杰克:20 = 220),日期 3 为 1700。谢谢!
  • 所以特殊余额是按人计算的,但总余额只取一次,每个日期?
  • 是 - 总余额只取一个人-日期出现的总数,但特殊余额的总和与人员出现在人员-日期对中的次数一样多。
  • 是的,效果很好!谢谢 - 我没有意识到这是一个非常复杂的需求。还有一个问题 - 在第二个任务中,我尝试将 Birth.Year 添加到第二个 group_by 命令,但收到错误:错误:未知列 'Birth.Year'
  • 嗯,当您在第一个 group_by %>% summarise() 命令中汇总数据时,您没有为 Birth.Year 添加列,因此它不存在于新数据集中。我会在第一个 summarise() 添加一列 Birth.Year=mean(Birth.Year)
【解决方案2】:

对于第二个示例(对于第一个示例,只需删除 Birth.Year):

library(dplyr)
example_data %>% group_by(Date, Birth.Year) %>%
                 mutate(special_sum = sum(Special_Balance),
                        total_loan_exposure = n( )) %>%
                 distinct(Name, Total_Balance) %>%
                 summarise(Total_balance_sum = sum(Total_Balance),
                           special_sum = special_sum[1],
                           total_people = n(),
                           total_loan_exposure = total_loan_exposure[1],
                           special_sum/Total_balance_sum)

【讨论】:

  • 这是一个优雅的解决方案 - 感谢您分享它。据我所知,您对包含 [1] 命令的两个命令做了什么?
  • 获取每个组的第一个值 - special_sum 和 total_loan_exposure 已作为 mutate 完成,因此我们没有删除其余行,但我们只需要该值一次。 Summarize 只需要一行,因此取第一行是获取值的一种方法。您可以通过在初始变异后停止并查看每个组的所有值都相同来检查这一点。
  • 他没有取两个确切数字的mean,而是取了那个数字的第一个索引。这是另一种实现与我在上面使用mean 的解决方案中所做的相同的事情的方法。如果您不知道如何索引向量、data.frames、列表,我推荐this hadley wickham 的高级 r 书的章节。
  • [1]mean() 快得多!
  • 是的,我知道。我的解决方案在处理时间方面较差。我只是表明,就最终结果而言,我们做了同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多