【问题标题】:Remove ID if any consecutive values does not meet threshold如果任何连续值不满足阈值,则删除 ID
【发布时间】:2019-02-07 20:49:48
【问题描述】:

我的数据框如下所示:

id        year        value
1         2000        23
1         2001        40
1         2003        93
2         1998        90
2         1999        91
2         2002        92
3         2015        12
3         2016        13
3         2017        14

如果有任何两个连续的值不符合90的阈值,我想删除该ID。注意:在这种情况下,连续,只是意味着一年又一年,不一定是一年之后。 (例如:ID 1 的 2001 年和 2003 年是连续年份)

输出应该只是 id 2。如果 id 2 有任何两个连续值

id        year        value
2         1998        90
2         1999        91
2         2002        92

【问题讨论】:

  • 欢迎来到 SO!你试过什么了?你在哪里卡住?请修改您的问题以符合reproducible example 的标准。

标签: r


【解决方案1】:

也可以:

library(dplyr)

df %>%
  group_by(id) %>%
  filter(!any(value < 90 & lag(value) < 90))

输出:

# A tibble: 3 x 3
# Groups:   id [1]
     id  year value
  <int> <int> <int>
1     2  1998    90
2     2  1999    91
3     2  2002    92

【讨论】:

  • 分组把它变成tibble 想要显示更漂亮的结果,你可以在最后做%&gt;% as.data.frame()
【解决方案2】:

此解决方案使用包dplyr

library(dplyr)

df1 %>%
  group_by(id) %>%
  filter(all(value[-1] >= 90 | value[-n()] >= 90))
## A tibble: 3 x 3
## Groups:   id [1]
#     id  year value
#  <int> <int> <int>
#1     2  1998    90
#2     2  1999    91
#3     2  2002    92

数据。

df1 <- read.table(text = "
id        year        value
1         2000        23
1         2001        40
1         2003        93
2         1998        90
2         1999        91
2         2002        92
3         2015        12
3         2016        13
3         2017        14                  
", header = TRUE)

【讨论】:

  • @arg0naut 我删除了向量的第一个元素和最后一个元素n()。所以这两个结果向量是滞后的,并且对 value[2]value[1] 进行 OR'ed,然后是 3 和 2,等等。
【解决方案3】:

使用dplyr,您可以先识别小于90的值。然后您可以计算序列中有多少条目小于90。之后您可以只保留您没有观察到2个连续值的id小于 90。

library(dplyr)
df %>%
  mutate(value_90 = value < 90) %>%
  group_by(id) %>%
  mutate(n_cons = cumsum(value_90)) %>%
  filter(!any(n_cons == 2)) %>%
  select(id, year, value)

# A tibble: 3 x 3
# Groups:   id [1]
     id  year value
  <dbl> <dbl> <dbl>
1     2  1998    90
2     2  1999    91
3     2  2002    92

【讨论】:

    【解决方案4】:

    使用 dplyr 和 rle...

    library(dplyr)
    DT %>% mutate(test = value < 90) %>% group_by(id) %>% filter(
      with(rle(test), !any(lengths >= 2 & values))
    ) %>% select(-test)
    
    # A tibble: 3 x 3
    # Groups:   id [1]
         id  year value
      <int> <int> <int>
    1     2  1998    90
    2     2  1999    91
    3     2  2002    92
    

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 2015-10-13
      • 1970-01-01
      相关资源
      最近更新 更多