【问题标题】:calculate difference between values in different row and different column计算不同行和不同列中的值之间的差异
【发布时间】:2018-07-25 22:21:05
【问题描述】:

我有一个这样的数据框:

ID  s1  e1  s2  e2
A   50  150 80  180
A   160 350 280 470
A   355 700 800 1150
B   100 500 150 550
B   550 1500    800 1750

当 ID 相同时,我想计算连续行但不同列中的值之间的差异(对于 ID A:第 2 行中的 s1 减去第 1 行中的 e1;第 3 行中的 s1 减去第 2 行中的 e1;第 2 行中的 s2 减去第 2 行中的 e2 row1; s2 in row3 减去 e2 in row2) 并将这些值添加到新列(diff1 和 diff2)。

然后数据框将如下所示:

ID  s1  e1  s2  e2  diff1   diff2
A   50  150 80  180     
A   160 350 280 470 10  100
A   355 700 800 1150    5   330
B   100 500 150 550     
B   550 1500    800 1750    50  250

这可能吗?

提前谢谢你

WD

【问题讨论】:

    标签: r dataframe dplyr data.table plyr


    【解决方案1】:

    按'ID'分组后,得到's1'的lead,从'e1'中减去它,并创建'diff1'作为此输出的lag。类似地,'diff2' 可以创建对应的 's2' 和 'e2' 列对

    library(dplyr)
    df1 %>%
        group_by(ID) %>%
        mutate(diff1 = lag(lead(s1) - e1), diff2 = lag(lead(s2)- e2))
    # A tibble: 5 x 7
    # Groups: ID [2]
    #   ID       s1    e1    s2    e2 diff1 diff2
    #   <chr> <int> <int> <int> <int> <int> <int>
    #1 A        50   150    80   180    NA    NA
    #2 A       160   350   280   470    10   100
    #3 A       355   700   800  1150     5   330
    #4 B       100   500   150   550    NA    NA
    #5 B       550  1500   800  1750    50   250
    

    如果有多个 's'、'e' 对,data.table 的一个选项是将 melt 转换为 'long' 格式,然后在进行必要的计算后将 dcast 转换为 'wide'

    library(data.table)
    dnew <- dcast(melt(setDT(df1, keep.rownames = TRUE),
     measure = patterns("^s\\d+", "^e\\d+"), value.name = c("s", "e"))[, 
      diffs := shift(shift(s, type = "lead") - e), .(ID, variable)][],
               rn + ID ~ paste0('diff', variable), value.var = 'diffs')
    df1[, names(dnew)[3:4] := dnew[, 3:4, with = FALSE]][, rn := NULL][]
    #   ID  s1   e1  s2   e2 diff1 diff2
    #1:  A  50  150  80  180    NA    NA
    #2:  A 160  350 280  470    10   100
    #3:  A 355  700 800 1150     5   330
    #4:  B 100  500 150  550    NA    NA
    #5:  B 550 1500 800 1750    50   250
    

    【讨论】:

    • 我注意到,当我只有一行 ID(带有一组 s1、e1、s2、e2)时,它也会计算与前一行(不同 ID)的差异,但我只需删除单个 ID 行即可解决此问题。
    • @WannesDermauw 我认为melt 需要成对列。您可以添加相应的“e”列的 NA 列,然后执行 melt
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2019-07-23
    • 2017-07-17
    相关资源
    最近更新 更多