如何找到分组的非连续行中的差异?

时间:2018-06-20 02:39:33

标签: r

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

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]和[7,4]-[8,4],[7,4]-[9,4],[7,4]-[ 10,4]等。我已经尝试过使用dplyr(突变)和data.base包的各种方法,但是仅弄清楚了如何运行连续的行,而无法弄清楚如何按id进行分组。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

您可以使用aveDist_coverID分组来完成所需的操作。

请注意,尽管该问题指出应按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))

答案 1 :(得分:1)

按“ ID”分组后,对“ Dist_cover”进行子集设置,其中“ OBS”为1(假设每个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))