- 已编辑
数据框:
aa=data.frame(数值=c(50,110,120,110,105,101,103,30,40,101,102,110),
字符=c(rep("a",2),rep("b",2),rep("a",3),"b",rep("a",4) ))
求: 返回连续3个及以上的"a"且数值大于100的最后一个符合条件的行号.即本例的第7行和12行.
数据框:
aa=data.frame(数值=c(50,110,120,110,105,101,103,30,40,101,102,110),
字符=c(rep("a",2),rep("b",2),rep("a",3),"b",rep("a",4) ))
求: 返回连续3个及以上的"a"且数值大于100的最后一个符合条件的行号.即本例的第7行和12行.
这是我的解法,可能有点复杂,欢迎更好的解法,我的想法是将字符
那一列转为字符串,然后借助正则表达式进行处理。
aa<-data.frame(数值=c(50,110,120,110,105,101,103,30,40,101,102,110),
字符=c(rep("a",2),rep("b",2),rep("a",3),"b",rep("a",4)))
library(stringr)
b<-Reduce(paste0,unlist(aa$字符))
locates<-str_locate_all(b,"a{3,}")[[1]]
for(i in 1:nrow(locates)){
start<-locates[i,][1]
end<-locates[i,][2]
flag<-rep('N',end-start+1)
bigger<-aa$数值[start:end]>100
for(j in 1:(end-start+1)){
if(bigger[j]){flag[j]<-'Y'}
}
row_num<-start:end
d<-Reduce(paste0,unlist(flag))
e<-str_locate_all(d,"Y{3,}")[[1]]
cat(row_num[e[,2]],'\n')
}
#> 7
#> 12
<sup>Created on 2021-04-05 by the reprex package (v2.0.0)</sup>
是有一些麻烦,特意分开了写,这样看的清楚些
library(data.table)
aa <- data.frame(num=c(50,110,120,110,105,101,103,30,40,101,102,110),str=c(rep("a",2),rep("b",2),rep("a",3),"b",rep("a",4) ))
setDT(aa)
# 根据条件,判断每一行是否符合条件
aa[,grp:= (str=="a" & num>100)][]
#> num str grp
#> 1: 50 a FALSE
#> 2: 110 a TRUE
#> 3: 120 b FALSE
#> 4: 110 b FALSE
#> 5: 105 a TRUE
#> 6: 101 a TRUE
#> 7: 103 a TRUE
#> 8: 30 b FALSE
#> 9: 40 a FALSE
#> 10: 101 a TRUE
#> 11: 102 a TRUE
#> 12: 110 a TRUE
# 判断是否为连续符合条件,连续符合即保持同一个index, 否则就递增
aa[,grp_index:=rleid(grp)][]
#> num str grp grp_index
#> 1: 50 a FALSE 1
#> 2: 110 a TRUE 2
#> 3: 120 b FALSE 3
#> 4: 110 b FALSE 3
#> 5: 105 a TRUE 4
#> 6: 101 a TRUE 4
#> 7: 103 a TRUE 4
#> 8: 30 b FALSE 5
#> 9: 40 a FALSE 5
#> 10: 101 a TRUE 6
#> 11: 102 a TRUE 6
#> 12: 110 a TRUE 6
# 判断连续有几个符合条件
aa[,count:=.N,by= grp_index][]
#> num str grp grp_index count
#> 1: 50 a FALSE 1 1
#> 2: 110 a TRUE 2 1
#> 3: 120 b FALSE 3 2
#> 4: 110 b FALSE 3 2
#> 5: 105 a TRUE 4 3
#> 6: 101 a TRUE 4 3
#> 7: 103 a TRUE 4 3
#> 8: 30 b FALSE 5 2
#> 9: 40 a FALSE 5 2
#> 10: 101 a TRUE 6 3
#> 11: 102 a TRUE 6 3
#> 12: 110 a TRUE 6 3
# 筛选3个以上且符合条件的每一组的最后一行
aa[grp==TRUE & count>=3,.I[.N],by = grp_index]$V1
#> [1] 7 12
<sup>Created on 2021-04-05 by the reprex package (v0.3.0)</sup>
frankzhang21 谢谢您的帮助,而且很清晰,超赞!