给出两个数据框:
C1<-c(3,4,4,4,5)
C2<-c(3,7,3,4,5)
C3<-c(5,6,3,7,4)
DF<-data.frame(C1=C1,C2=C2,C3=C3)
DF
C1 C2 C3
1 3 3 5
2 4 7 6
3 4 3 3
4 4 4 7
5 5 5 4
和
V1<-c(3,2,2,4,5)
V2<-c(3,7,3,5,2)
V3<-c(5,2,5,7,5)
V4<-c(1,1,2,3,4)
V5<-c(1,2,6,7,5)
DF2<-data.frame(V1=V1,V2=V2,V3=V3,V4=V4,V5=V5)
DF2
V1 V2 V3 V4 V5
1 3 3 5 1 1
2 2 7 2 1 2
3 2 3 5 2 6
4 4 5 7 3 7
5 5 2 5 4 5
查看两个数据帧中的每个等效行,C3中的值与我想要在DF2中的同一行中删除的列数之间存在关系。
C3中的值与要删除的DF2中的列数之间的关系如下所示
If C3≥7 drop V5
If C3=6.0:6.9 drop V4 and up (so basically V5,V4)
If C3=5.0:5.9 drop V3 and up (so basically V5,V4,V3)
If C3=4.0:4.9 drop V2 and up (so basically V5,V4,V3,V2)
If C3≤3.9 drop entire row
对于这个例子,基于C3的值,我希望DF2看起来像这样
V1 V2 V3 V4 V5
1 3 3
2 2 7 2
4 4 5 7 3
5 5
我已经尝试过编写一个简单的脚本来执行此操作(我很新,所以我喜欢保持简单,所以我可以看到发生了什么)但是我左右抛出错误所以我很欣赏一些关于如何进行的建议
答案 0 :(得分:4)
也许最简单的方法就是:
DF3 <- DF2
for (i in seq_len(nrow(DF3))) {
DF3[i, seq_len(ncol(DF3)) >= DF[i, ]$C3 - 2] <- NA
}
DF3
然后,
> DF3
V1 V2 V3 V4 V5
1 3 3 NA NA NA
2 2 7 2 NA NA
3 NA NA NA NA NA
4 4 5 7 3 NA
5 5 NA NA NA NA
答案 1 :(得分:4)
我喜欢Koshke的回答,但是如果您设置为NA
的规则对他们没有很好的数学属性,或者您需要任意定义规则,那么这种方法应该给您灵活性。首先,定义一个函数,根据您的规则返回要删除的列:
f <- function(x) {
if(x >= 7){
out <- 5
}else if(x >= 6.0){
out <- 4:5
} else if( x >= 5.0){
out <- 3:5
} else if (x >= 4.0){
out <- 2:5
} else {
out <- 1:5
}
return(out)
}
接下来,为要删除的列索引创建一个列表:
z <- lapply(DF$C3, f)
最后,遍历每一行,将相应的列设置为NA:
for(j in seq(length(z))){
DF2[j, z[[j]]] <- NA
}
#-----
V1 V2 V3 V4 V5
1 3 3 NA NA NA
2 2 7 2 NA NA
3 NA NA NA NA NA
4 4 5 7 3 NA
5 5 NA NA NA NA
答案 2 :(得分:2)
使用定义的切割点对kohske的答案略有不同:
breaksx <- cut(DF$C3,c(0,3,4,5,6,7,Inf),labels=FALSE)
for (i in seq(nrow(DF2))) {
DF2[i,breaksx[i]:ncol(DF2)] <- NA
}
结果:
> DF2
V1 V2 V3 V4 V5
1 3 3 NA NA NA
2 2 7 2 NA NA
3 NA NA NA NA NA
4 4 5 7 3 NA
5 5 NA NA NA NA
删除所有NA的行
DF2[apply(DF2,1,function(x) !all(is.na(x))),]
结果:
V1 V2 V3 V4 V5
1 3 3 NA NA NA
2 2 7 2 NA NA
4 4 5 7 3 NA
5 5 NA NA NA NA