使用基于组的汇总值创建新变量
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_join
ed 这两个数据集就这样
left_join(data, data2)
我本可以指定by = countries
,但我不必这样做,因为它是两个数据集中唯一的公共变量。
虽然这解决了问题并且我永远感谢 r2evans,但我仍然想知道一步解决方案。有的话请留言。
【讨论】:
以上是关于使用基于组的汇总值创建新变量的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用<-操作符创建新的变量使用transform函数基于两个数据列的加和创建新的变量(sum variables to make new featurs in dataframe)