删除特定年份范围之外的行,而无需在R

时间:2018-08-31 20:50:26

标签: r for-loop dataframe grouping

我正在寻找一种方法来省略不在两个特定值之间的行,而无需使用for循环。年列中的所有行都在1999年至2002年之间,但是其中一些不包括这两个日期之间的所有年。您可以看到以下原始数据:

a <- data.frame(year = c(2000:2002,1999:2002,1999:2002,1999:2001), 
                id=c(4,6,2,1,3,5,7,4,2,0,-1,-3,4,3))

   year id
1  2000  4
2  2001  6
3  2002  2
4  1999  1
5  2000  3
6  2001  5
7  2002  7
8  1999  4
9  2000  2
10 2001  0
11 2002 -1
12 1999 -3
13 2000  4
14 2001  3

处理后的数据集应仅包括1999:2002之间的连续行。以下data.frame正是我所需要的:

  year id
1 1999  1
2 2000  3
3 2001  5
4 2002  7
5 1999  4
6 2000  2
7 2001  0
8 2002 -1

当我执行以下for循环时,我得到了上一个data.frame,没有任何问题:

for(i in 1:which(a$year == 2002)[length(which(a$year == 2002))]){
  if(a[i,1] == 1999 & a[i+3,1] == 2002){
    b <- a[i:(i+3),]
  }else{next}

  if(!exists("d")){
    d <- b
  }else{
    d <- rbind(d,b)
  }
}

但是,我有超过100万行,我需要在不使用for循环的情况下执行此过程。有什么更快的方法吗?

3 个答案:

答案 0 :(得分:0)

有一个功能可以自动执行此操作。

首先,使用命令dplyrtidyverse安装名为install.packages("dplyr")install.packages("tidyverse")的软件包。

然后,用library(dplyr)加载程序包。

然后,使用filter函数:a_filtered = filter(a, year >=1999 & year < 2002)

即使有很多行,这也应该很快。

答案 1 :(得分:0)

您可以尝试一下。首先,我们创建连续数字的组,然后加入完整的日期范围,然后过滤是否有不完整的组。如果您已有分组变量,则可以将其减少很多。

library(tidyverse)

df <- data_frame(year = c(2000:2002,1999:2002,1999:2002,1999:2001), 
                id=c(4,6,2,1,3,5,7,4,2,0,-1,-3,4,3))

df %>% 
  mutate(groups = cumsum(c(0,diff(year)!=1))) %>% 
  nest(-groups) %>%
  mutate(data = map(data, .f = ~full_join(.x, data_frame(year = 1999:2002), by = "year")),
         drop = map_lgl(data, ~any(is.na(.x$id)))) %>%
  filter(drop == FALSE) %>% 
  unnest() %>%
  select(-c(groups, drop))
#> # A tibble: 8 x 2
#>    year    id
#>   <int> <dbl>
#> 1  1999     1
#> 2  2000     3
#> 3  2001     5
#> 4  2002     7
#> 5  1999     4
#> 6  2000     2
#> 7  2001     0
#> 8  2002    -1

reprex package(v0.2.0)于2018-08-31创建。

答案 2 :(得分:0)

我们也可以通过以下方式来实现此目的:根据逻辑表达式创建一个分组列,检查'year'1999,然后将filter'year'检查为'1999',{{1} }}表示为'2002',而first last表示特定的'grp'之间的'年份'

if