【问题标题】:Remove rows in dataframe, which are not consecutive删除数据框中不连续的行
【发布时间】:2019-12-11 13:57:57
【问题描述】:

我的问题是related to my other question,但并不完全相同。

假设我有这个:

DOY  <-c (1:30) # Day of Year
rain <-c (0,0,0,0,0,0,10,0,0,20,10,5,0,0,0,0,0,0,0,5,20,45,5,2,0,0,0,10,0,0)
DF <- data.frame(DOY=DOY, rain=rain)
# Just interested in days with rain
DF <- DF[DF$rain > 0,] 
# assign ID for each rainfall event, but only if Difference in days is >4
DF$ID <-c (1,1+cumsum(diff(DF$DOY) > 4)) 

# Rerranging, so I have the highest value at top for each group
DF <- DF %>%
  group_by(ID) %>%
  arrange(desc(rain),.by_group=TRUE) 

我的DF 看起来像这样:

DOY rain    ID
10    20     1
 7    10     1
11    10     1
 9     9     1
12     5     1
22    45     2
21    20     2
28    10     2
20     5     2
23     5     2
24     2     2

但只需要从最大值之日起连续的天数。我的预期输出应该是:

DOY rain    ID
10    20     1
11    10     1
 9     9     1
12     5     1
22    45     2
21    20     2
20     5     2
23     5     2
24     2     2

在我的情况下,应删除 DOY = 7 和 DOY 28 的行,保留所有其他 DOY。

【问题讨论】:

  • 第三行不连续
  • “从最大值之日起连续的天数”到底是什么意思?对我来说,最大值的日子是 DOY==22 (rain==45) 所以你应该只保留 DOY==20 和 DOY==22,这似乎不是你想要的。您的帖子通过可重复的示例做得很好,但您的预期输出尚不清楚。
  • @TiltingTrain - 根据您的示例,您想为每个 id 返回连续 DOY 序列吗?例如 [9, 10, 11] 表示 id=1,或者 [21, 22, 23, 24] 表示 id=2? id=1 可以有两个序列 [9, 10, 11] 和 [21, 22, 23] 吗?你想保留两者吗?
  • @OttoKässi - 是的,我想返回每个 ID 的连续 DOY 序列,因此 ID=1 为 [9,10,11,12],ID= 为 [21,22,23,24] 2.并且最大值也应该在这个序列中,这就是我按最大值排序的原因
  • @DanChaltiel - 我对 OttoKässi 的最后评论是否可以澄清我的预期输出应该是什么?

标签: r dataframe dplyr


【解决方案1】:

我认为您可以在此处重复使用其他问题的答案(顺便说一句,这是一个非常巧妙的技巧)。

DF %>%
  group_by(ID) %>%
  arrange(DOY,.by_group=TRUE) %>%
  mutate(
    max_rain = max(rain),
    i=cumsum(c(TRUE,diff(DOY)>1))
  ) %>%
  group_by(i, ID) %>%
  filter(any(rain==max_rain))

基本上,对于每个 ID,您保存最大降雨量并创建另一个排序组 ID(此处为i)。您必须通过DOY 安排此功能。

然后,您只需按 ID 分组并过滤掉所有不包含最大降雨值的组。

【讨论】:

  • 非常感谢!我以为我必须以某种方式拯救最大的降雨,但我总是卡住了。现在这对我有很大帮助,非常感谢。
【解决方案2】:

这是我的方法:

DF %>% arrange(ID, DOY) %>% 
       group_by(ID) %>% 
       mutate(lDOY = lag(DOY)) %>% 
       slice(c(min(which(DOY - lDOY == 1) -1), which(DOY - lDOY == 1))) %>%
       select(-lDOY) %>%
       arrange(ID, -rain)

这里我们先按天和ID排序,使用slice只保留相邻DOY的tge差为1的观察结果。 slice()中的min()部分是用来保留每个序列的第一个观察结果的。最后,输出按id和rain排序。

请注意,这只有在每个 id 都有一个序列时才有效。

【讨论】:

  • 这个也可以,也正是我想要的。我忘了说,实际上,要按 DOI 再次对其进行排序,但这可以通过group_by 轻松完成。而且一个ID总是有一个序列,所以应该没有问题
猜你喜欢
  • 2018-03-14
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多