【问题标题】:Dplyr: subtracting within uneven factor levelsDplyr:在不均匀的因子水平内减去
【发布时间】:2023-03-06 13:31:01
【问题描述】:

我正在努力学习dplyr,但对于 Stackoverflow 或文档中相对简单的问题,我找不到答案。我想我会在这里问。

我有一个如下所示的 data.frame:

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=="a" 中减去与factor_2=="b" 关联的值number 列。

生成的 data.frame 的第一行如下所示:

        diff factor_1
1    3.880291        1        

需要注意的是,factor_2 的每个级别并不总是在 factor_1 的每个级别中都有值。如果是这种情况,我想将0 分配给与缺失因子水平相关的number

感谢您的帮助。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这是一种方法:

    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 的交互导致你的解决方案一开始就不起作用(不知何故?)。
    【解决方案2】:

    这是使用您的数据的快速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
    

    【讨论】:

    • 干杯,我编辑了问题以包括 set.seed(1) b/c marat 使用过的那个。感谢您复制和粘贴我的号码!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2015-03-27
    • 2011-03-16
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    相关资源
    最近更新 更多