【问题标题】:How to find the difference in non-consecutive rows that are grouped?如何找到分组的非连续行的差异?
【发布时间】:2018-06-20 02:39:32
【问题描述】:

我有一个包含数千条记录的数据框。我的数据框如下所示:

Row     ID     OBS      Dist_cover
1       2       1           60
2       2       0          140
3       2       0           15
4       2       0          147
5       2       0           37
6       2       0           89
7       3       1          239
8       3       0           62
9       3       0           11
10      3       0          193

我需要在Dist_cover 中找到“1”和“0”OBS 值之间的差异...但按 id 分组。本质上,我正在寻找 [1,4] - [2,4]、[1,4] - [3,4]、[1,4] - [4,4]、[1,4] 之间的区别- [5,4], [1,4] - [6,4] AND [7,4] - [8,4], [7,4] - [9,4], [7,4] - [ 10,4] 等。我尝试了使用 dplyr (mutate) 和 data.base 包的各种方法,但只知道如何运行连续行,不知道如何按id 分组。有什么想法吗?

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用ave 完成您想要的操作,将Dist_cover 分组为ID

    请注意,尽管问题指出应该按OBS 进行分组,但这实际上是不需要的。等于 1 的 OBS 始终是第一个,就像问题中(隐式)说明的那样。 OP 想要 “[1,4] - [2,4]、[1,4] - [3,4] 等之间的差异”

    ave(dat$Dist_cover, dat$ID, FUN = function(x) x - x[1])
    #[1]    0   80  -45   87  -23   29    0 -177 -228  -46
    

    数据。

    dat <-
    structure(list(Row = 1:10, ID = c(2L, 2L, 2L, 2L, 2L, 2L, 3L, 
    3L, 3L, 3L), OBS = c(1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), 
    Dist_cover = c(60L, 140L, 15L, 147L, 37L, 89L, 239L, 62L, 
    11L, 193L)), .Names = c("Row", "ID", "OBS", "Dist_cover"), class = "data.frame", row.names = c(NA, 
    -10L))
    

    【讨论】:

    • @Hack-R 是的,我知道,但是等于 1 的 OBS 始终是第一个,就像问题中(隐含地)说明的那样。 OP 想要 “[1,4] - [2,4]、[1,4] - [3,4] 等之间的差异”
    【解决方案2】:

    在按“ID”分组后,将“OBS”为 1 的“Dist_cover”子集(假设每个 ID 只有一个 1 实例),从“Dist_covert”中减去它,然后 filter 的值其中“OBS”为 0。

    library(dplyr)
    df1 %>% 
      group_by(ID) %>%
      mutate(Diff = Dist_cover[OBS==1] - Dist_cover) %>% 
      # if OBS is 1 occurs always as the first observation for ID
      # mutate(Diff = first(Dist_cover) - Dist_cover) %>% 
      filter(OBS == 0)
    

    数据

    df1 <- structure(list(Row = 1:10, ID = c(2L, 2L, 2L, 2L, 2L, 2L, 3L, 
    3L, 3L, 3L), OBS = c(1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), 
        Dist_cover = c(60L, 140L, 15L, 147L, 37L, 89L, 239L, 62L, 
        11L, 193L)), .Names = c("Row", "ID", "OBS", "Dist_cover"),
      class = "data.frame", row.names = c(NA, 
    -10L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多