【问题标题】:Update dplyr filter per row每行更新 dplyr 过滤器
【发布时间】:2020-10-25 12:41:59
【问题描述】:

假设我有以下数据:

structure(list(A = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
), B = c(1, 2, 3, 4, 20, 5, 1, 2, 6, 3, 4, 5, 6, 7)), row.names = c(NA, 
-14L), class = "data.frame")

我现在希望删除 B 的增量不为 1 的所有行,但 A 列开始新系列时除外。 我试图通过使用dplyr 来做到这一点:

filter(df, (diff(append(B,NA,after=0))==1 | B==1))

请注意,我追加是因为diff() 之后的向量比原始数据短 1。 这导致:

structure(list(A = c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2), B = c(1, 
2, 3, 4, 1, 2, 4, 5, 6, 7)), row.names = c(NA, -10L), class = "data.frame")

问题是因为我使用diff()来判断B列的增量是否始终为1,一旦数据出现错误,也会(错误地)将错误后的那一行视为错误。 有没有办法:

  • 使用更合乎逻辑的方法来规避这个问题?

  • 或者是否有可能使过滤器在删除一行后更新,以便 diff() 的逻辑是正确的。虽然我想如果可能的话,这会显着减慢命令的速度。

【问题讨论】:

  • 为什么要使用结构来创建数据框,为什么不使用像tibble( A = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2), B = c(1, 2, 3, 4, 20, 5, 1, 2, 6, 3, 4, 5, 6, 7))这样的小标题
  • 确实简单一些,谢谢!我不太确定如何生成清晰的假数据,所以在 R 中手工制作,然后使用 dput。谢谢推荐!

标签: r dplyr


【解决方案1】:

这行得通吗:

> library(dplyr)
> dat %>% group_by(A) %>% mutate(C = case_when(B - lag(B) != 1 & B - lag(B, n = 2) == 1 ~ 0, TRUE ~ 1)) %>%
+   mutate(C = lead(C, default = 1)) %>% filter(C == 1)
# A tibble: 12 x 3
# Groups:   A [2]
       A     B     C
   <dbl> <dbl> <dbl>
 1     1     1     1
 2     1     2     1
 3     1     3     1
 4     1     4     1
 5     1     5     1
 6     2     1     1
 7     2     2     1
 8     2     3     1
 9     2     4     1
10     2     5     1
11     2     6     1
12     2     7     1
> 

【讨论】:

  • 不像你的那么优雅,但它也能胜任。 dat %&gt;% group_by(A) %&gt;% mutate( lag1_dff = B - lag(B, n = 1), lag2_diff = B - lag(B, n = 2) ) %&gt;% filter(lag1_dff == 1 | lag2_diff == 1 | is.na(lag1_dff)) %&gt;% # is.na to capture the first value in B select(A, B)
  • @Karthik S 确实可以!这肯定适用于我当前的数据,谢谢!为了将来参考,是否可以自动扩展 lag(B, n = 2) 部分,以便即使连续有许多错误的观察结果仍然可以纠正?还是必须手动完成? (例如lag(B, n = 3 ) 等)
  • lag 函数中的“n”值表示您要向后看多少行,因此您可以根据数据更改数字。
猜你喜欢
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多