简体   繁体   English

根据行的值删除列

[英]Deleting columns based on the value of a row

Given two data frames: 给出两个数据框:

 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

and

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

Looking at each equivalent row in both data frames, there is a relationship between the value in C3 and the number of columns I want to drop in that same row in DF2. 查看两个数据帧中的每个等效行,C3中的值与我想要在DF2中的同一行中删除的列数之间存在关系。

The relationship between the value in C3 and the # of columns in DF2 to drop looks like this 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

For this example, based on the values of C3, I would want DF2 to look like this 对于这个例子,基于C3的值,我希望DF2看起来像这样

  V1 V2 V3 V4 V5
1  3  3
2  2  7  2

4  4  5  7  3 
5  5

I've tried write a simple script to do this (I'm pretty new so I like to keep things simple so I can see what's going on) but I'm throwing errors left and right so I'd appreciate some advice on how to proceed 我已经尝试写一个简单的脚本来做这个(我很新,所以我喜欢保持简单,所以我可以看到发生了什么)但是我左右抛出错误所以我很欣赏一些关于如何做的建议继续

Perhaps the easiest way is like: 也许最简单的方法是:

DF3 <- DF2
for (i in seq_len(nrow(DF3))) {
  DF3[i, seq_len(ncol(DF3)) >= DF[i, ]$C3 - 2] <- NA
}
DF3

then, 然后,

> 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

I like Koshke's answer, but if your rules for setting to NA don't have a nice mathematical property to them or you need to define your rules arbitrarily, this approach should give you that flexibility. 我喜欢Koshke的答案,但是如果你设置为NA规则没有给他们很好的数学属性,或者你需要任意定义你的规则,这种方法应该给你灵活性。 First, define a function that returns the columns to drop based on your rules: 首先,定义一个函数,根据您的规则返回要删除的列:

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)
}

Next, create a list for the column indices to drop: 接下来,为要删除的列索引创建一个列表:

z <- lapply(DF$C3, f)

Finally, loop through each row setting the corresponding columns to NA: 最后,遍历每一行,将相应的列设置为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

A slight variation on kohske's answer using defined cut points: 使用定义的切割点对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
}

Result: 结果:

> 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

To remove the rows which are all NAs 删除所有NA的行

DF2[apply(DF2,1,function(x) !all(is.na(x))),]

Result: 结果:

  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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM