我有一个数据框。为简单起见,我省略了许多列和行:
Distance Type
1 162 A
2 27182 A
3 212 C
4 89 B
5 11 C
我需要在数据帧中找到6个连续的行,这样平均距离就是1000,并且考虑的唯一类型是A或B.只是为了澄清,人们可能会认为过滤掉所有的C行,并且然后继续,但是那些原本不是连续的行在过滤时将变为连续的,这并不好。
例如,如果我过滤掉上面的第3行和第5行,我会留下3行。如果我提供了更多行,那可能会产生错误的结果。
答案 0 :(得分:0)
也许是data.table库的解决方案?
为了重现性,这里有一个数据样本,基于你所写的内容。
library(data.table)
# data orig (with row numbers...)
DO<-"Distance Type
1 162 A
2 27182 A
3 212 C
4 89 B
5 11 C
6 1234 A"
# data : sep by comma
DS<-gsub('[[:blank:]]+',';',DO)
# data.frame
DF<-read.table(textConnection(DS),header=T,sep=';',stringsAsFactors = F)
#data.table
DT<-as.data.table(DF)
然后,每次找到相同值的序列时,创建一个递增计数器的函数:
# function to set sequencial group number
mkGroupRep<-function(x){
cnt=1L
grp=1L
lx<-length(x)
ne<- x[-lx] != x[-1L] #next not equal
for(i in seq_along(ne)){if(ne[i])cnt=cnt+1;grp[i+1]=cnt}
grp
}
并将其与data.table一起使用'通过引用进行多次分配':
# update dat : set group number based on sequential type
DT[,grp:=mkGroupRep(Type)]
# calc sum of distance and number of item in group, by group
DT[,`:=`(
distMean=mean(Distance),
grpLength=.N
),by=grp]
# filter what you want :
DT[Type != 'C' & distMean >100 & grpLength==2 | grpLength==3]
输出:
Distance Type grp distMean grpLength
1: 162 A 1 13672 2
2: 27182 A 1 13672 2