使用基于组的汇总值创建新变量

Posted

技术标签:

【中文标题】使用基于组的汇总值创建新变量【英文标题】:Creating new variable with summary values based on group 【发布时间】:2019-10-29 12:39:09 【问题描述】:

我真的有两个问题。我很确定第二个会帮助我解决第一个,但我可能完全走错了路,可能会有更简单的解决方案。

第一个问题:我想用 ggplot2 和 geom_bar 制作一个堆积条形图。我有 4 个离散间隔(年)的许多国家的时间序列数据。我知道将时间序列数据显示为条形图是非正统的(我愿意接受其他建议)。我想要做的是将条形图显示为分面网格(按年份),其中国家以相同的降序显示,基于我所有 4 年中所有 4 个变量的总和。我只想显示前 25 个国家/地区。

为此,我一直在使用 dplyr 管道和 ggplot 的组合。

起初,我用

计算了一个新列
 data %>% 
  rowwise() %>% 
  mutate(total = sum(var1, var2, var3, var4, na.rm = T) %>% 
  arrange(desc(total)) %>% 
  top_n(100, total) %>% 
  ggplot...

但这只会显示每个国家/地区对的总数,并且会产生一些副作用,例如将某些国家/地区的某些年份留空,因为这些年份的值没有进入前 100 名。

接下来我尝试使用 summarise 函数将所有 4 年的 4 个变量相加,如下所示:

 data %>% 
  summarize(sum = sum(var1, var2, var3, var4, na.rm = T))

但这会将我的表格减少到两列,我知道这是所需的输出,但我不知道如何将这个新的总和分配给每个国家的所有年份。

我将尝试在此处重现这两个问题:

一些数据:

 countries <- c("country A", "country B", "country C", "country D", "country E")
  years <- rep(c(2014, 2015, 2016, 2017), 5)
  set.seed(123)
  var1 <- sample(1:1000, 20)
  var2 <- sample(1:1000, 20)
  var3 <- sample(1:1000, 20)
  var4 <- sample(1:1000, 20)
  data <- data.frame(countries, years, var1, var2, var3, var4)

  data %>% 
   rowwise() %>% 
   mutate(total = sum(var1, var2, var3, var4, na.rm = T)) %>% 
   gather(key, value, 3:6) %>% 
   top_n(32, total) %>% 
    ggplot(., aes(x = countries, y = value, fill = key)) + 
     geom_col() + 
     facet_grid(cols = vars(years)) + 
     coord_flip()

正如您所见,正如代码所预期的那样,R 计算了每个国家/地区对的总和,而不是每个国家/地区所有年份的总和。我严重迷失了如何进行。任何帮助表示赞赏!

如果有什么不同:Var3 和 Var4 中有很多 NA。

我忘了说明第二个问题:

  data %>% 
   group_by(countries) %>% 
   summarize(sum = sum(var1, var2, var3, var4, na.rm = T))

返回一个包含国家和总和的表格,但是如何将这个新列重新分配给我的原始数据框?

【问题讨论】:

TeaTree,我编辑了格式化问题,然后您最近的编辑取消了工作。虽然我觉得这里有一点 python 式的缩进,但我的意图主要是为了可读性,并不是说这是每个人都应该使用的缩进样式。当我必须水平滚动代码时,这通常是一种麻烦和威慑。更不用说我觉得它打败了dplyr 动词提供的 literate programming 的优势之一。 非常抱歉!我看到有人在编辑,但不知道我会撤消你的工作......有没有办法协调 git 样式的更改? 别担心,我不介意,这是你的问题,我的编辑仍然只是对 OP 的建议。但我不想和其他人卷入编辑大战(这已经发生了),所以我在第一次撤消后就停下来了。如果您有兴趣,可以在问题历史记录中查看我的修改。 好的,我实现了缩进样式。更具可读性! 我现在有点紧张,当 SO 允许时(一三天内?),您可以自己回答并自我接受。很高兴你解决了! 【参考方案1】:

在 r2evans 之后,这为我解决了问题:

我首先总结了所有的值并将其保存到一个新的数据集

data2 <- data %>% 
 group_by(countries) %>% 
 summarize(sum = sum(var1, var2, var3, var4, na.rm = T))

然后我left_joined 这两个数据集就这样

 left_join(data, data2)

我本可以指定by = countries,但我不必这样做,因为它是两个数据集中唯一的公共变量。

虽然这解决了问题并且我永远感谢 r2evans,但我仍然想知道一步解决方案。有的话请留言。

【讨论】:

以上是关于使用基于组的汇总值创建新变量的主要内容,如果未能解决你的问题,请参考以下文章

用于交替值组的 Pyspark 自动增量

需要帮助使用局部变量减去具有多个组的前一行值

使用Spark中的复杂条件和滞后自引用创建新列

R语言使用<-操作符创建新的变量使用transform函数基于两个数据列的加和创建新的变量(sum variables to make new featurs in dataframe)

基于操作系统原理的Linux 的用户管理

如何根据使用 dplyr 的组上的聚合函数计算新列(在汇总统计信息上添加汇总统计信息)?