【问题标题】:How do I remove offsetting rows in a tibble?如何删除小标题中的偏移行?
【发布时间】:2017-12-11 15:43:40
【问题描述】:

我正在尝试删除具有偏移值的行。

library(dplyr)
a <- c(1, 1, 1, 1, 2, 2, 2, 2,2,2)
b <- c("a", "b", "b", "b", "c", "c","c", "d", "d", "d")
d <- c(10, 10, -10, 10, 20, -20, 20, 30, -30, 30)
o <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
df <- tibble(ID = a, SEQ = b, VALUE = d, OTHER = o)

生成这个按 ID 和 SEQ 分组的有序表。

> df
# A tibble: 10 x 4
      ID   SEQ VALUE OTHER
   <dbl> <chr> <dbl> <chr>
 1     1     a    10     A
 2     1     b    10     B
 3     1     b   -10     C
 4     1     b    10     D
 5     2     c    20     E
 6     2     c   -20     F
 7     2     c    20     G
 8     2     d    30     H
 9     2     d   -30     I
10     2     d    30     J

我想删除行对 (2,3)、(5,6)、(8,9),因为 VALUE 会否定匹配的前一行中的 VALUE。

我希望结果表是

> df2
# A tibble: 4 x 4
     ID   SEQ VALUE OTHER
  <dbl> <chr> <dbl> <chr>
1     1     a    10     A
2     1     b    10     D
3     2     c    20     G
4     2     d    30     J

我知道我不能使用group_by %&gt;% summarize,因为我需要保留 OTHER 中的值。我查看了dplyr::lag() 函数,但我看不出它有什么帮助。我相信我可以使用某种类型的 for each 循环遍历表并生成可用于删除行的逻辑向量,但我希望有一个更优雅的解决方案。

【问题讨论】:

  • 您似乎提出了一个问题,得到了答案,接受了答案,几个小时后您正在编辑问题。这很糟糕——它正在“移动球门柱”。相反,我建议创建一个新问题,链接到这个问题,并解释为什么原来的答案不起作用。
  • 谢谢 - 将尝试恢复并遵循您的建议。

标签: r


【解决方案1】:

怎么样:

vec <- cbind(
               c(head(df$VALUE,-1) + df$VALUE[-1], 9999) ,
               df$VALUE + c(9999, head(df$VALUE,-1))
             )

vec <- apply(vec,1,prod)
vec <- vec!=0
df[vec,]
# A tibble: 4 x 4
     ID   SEQ VALUE OTHER
  <dbl> <chr> <dbl> <chr>
1     1     a    10     A
2     1     b    50     D
3     2     c    60     G
4     2     d    70     J

这个想法是把你的VALUE 字段减去它的一个子集版本。当结果为 0 时,删除该行。

【讨论】:

  • 很好,您的解决方案甚至适用于我刚刚发现的边缘情况。我将把它应用到我的现实问题中,看看会发生什么。
  • 如果您发现问题,请尝试找出问题并使其在您的示例中可重现。
  • 做了一些修改,想法几乎相同,但我必须重复两次。它不是很优雅,但应该更健壮。只需调整 9999 值,这样您的实际数据就不会出现问题。我添加了这个有一个length=10 向量。
【解决方案2】:

这是dplyr 的另一个解决方案。不确定您在 cmets 中提到的边缘情况,但请随时使用我的解决方案对其进行测试:

library(dplyr)

df %>%
  group_by(ID, SEQ) %>%
  mutate(diff = VALUE + lag(VALUE),
         diff2 = VALUE + lead(VALUE)) %>%
  mutate_at(vars(diff:diff2), funs(coalesce(., 1))) %>%
  filter((diff != 0 & diff2 != 0)) %>%
  select(-diff, -diff2)

结果:

# A tibble: 4 x 4
# Groups:   ID, SEQ [4]
     ID   SEQ VALUE OTHER
  <dbl> <chr> <dbl> <chr>
1     1     a    10     A
2     1     b    50     D
3     2     c    60     G
4     2     d    70     J

注意:

此解决方案首先创建两个diff 列,一个添加lag,另一个添加VALUElead 到每个VALUE。只有偏移列在diffdiff2 中为零,所以我过滤掉了这些行,得到了所需的输出。

【讨论】:

  • 我不知道leadlag。很高兴知道,谢谢。
猜你喜欢
  • 2018-05-25
  • 1970-01-01
  • 2016-12-17
  • 2020-03-25
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
相关资源
最近更新 更多