Dplyr:在不均匀因子水平内进行减法

4

我正在尝试学习 dplyr,但是在 Stackoverflow 或文档中,我找不到一个相对简单的问题的答案。所以我决定在这里问一下。

我有一个看起来像这样的数据框:

set.seed(1)
dat<-data.frame(rnorm(10,20,20),rep(seq(5),2),rep(c("a","b"),5))
names(dat)<-c("number","factor_1","factor_2")
dat<-dat[order(dat$factor_1,dat$factor_2),]
dat<-dat[c(-3,-7),]



       number factor_1 factor_2
1   7.470924        1        a
6   3.590632        1        b
2  23.672866        2        b
3   3.287428        3        a
8  34.766494        3        b
4  51.905616        4        b
5  26.590155        5        a
10 13.892232        5        b

我想使用 dplyr 来减去每个因素一级别中与 factor_2=="b" 相关联的 number 列的值,从 factor_2=="a" 中减去。
结果数据框的第一行应如下所示:
        diff factor_1
1    3.880291        1        

需要注意的是,在每个factor_1级别中,并不总是存在每个factor_2级别的值。如果是这种情况,我希望将与缺失因子级别相关联的number赋值为0

感谢您的帮助。

2个回答

4
这里提供一种方法:
set.seed(1)
dat<-data.frame(rnorm(10,20,20),rep(seq(5),2),rep(c("a","b"),5))
names(dat)<-c("number","factor_1","factor_2")
dat<-dat[order(dat$factor_1,dat$factor_2),]
dat<-dat[c(-3,-7),]
#      number factor_1 factor_2
#1   7.470924        1        a
#6   3.590632        1        b
#2  23.672866        2        b
#3   3.287428        3        a
#8  34.766494        3        b
#4  51.905616        4        b
#5  26.590155        5        a
#10 13.892232        5        b

library(dplyr)
dat %>% 
  group_by(factor_1) %>% 
  summarize(diff=number[match('a',factor_2)]-number[match('b',factor_2)]) -> 
  d2

d2$diff[is.na(d2$diff)] <- 0

d2
# Source: local data frame [5 x 2]
# 
#   factor_1       diff
# 1        1   3.880291
# 2        2   0.000000
# 3        3 -31.479066
# 4        4   0.000000
# 5        5  12.697923

谢谢!你的解决方案完美地解决了我的问题。我之前已经加载了 plyr 来解决这个问题,但是 dplyrplyr 的交互导致一开始你的解决方案无法正常工作(不知道为什么?)。 - bjoseph

4

以下是使用您的数据的data.table快速解决方案(下次在使用rnorm生成数据集时,请使用set.seed

library(data.table)
setDT(dat)[order(-factor_2), if(.N == 1L) 0 else diff(number), by = factor_1]
#    factor_1        V1
# 1:        1  18.20020
# 2:        2   0.00000
# 3:        3 -51.88444
# 4:        4   0.00000
# 5:        5  61.90332

1
干杯,我编辑了问题并包含了 set.seed(1),因为Marat使用了它。感谢您复制并粘贴我的数字! - bjoseph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接