我正在寻找一种方法来省略不在两个特定值之间的行,而无需使用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
循环的情况下执行此过程。有什么更快的方法吗?
答案 0 :(得分:0)
有一个功能可以自动执行此操作。
首先,使用命令dplyr
或tidyverse
安装名为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