如果R中的语句:测试和动作的向量

时间:2013-09-05 19:10:06

标签: r

一些示例数据:

ID        S1Qual    S2Qual    S3Qual    S1        S2        S3
1         1         0         1         7         8         7
2         1         1         1         6         6         8
3         0         1         1         7         8         8
...

S1Qual,S2Qual和S3Qual分别表示S1PS,S2PS和S3PS的质量。如果[n, S1Qual] == 1,我想保留[n, S1PS];如果[n,S1Qual] == 0,我想设置[n,S1PS] == NA

我有以下代码:

n <- 1

while (n <= number.of.rows) {

    if (data$S1Qual[n] == 0) {data$S1[n] <- NA}
    if (data$S2Qual[n] == 0) {data$S2[n] <- NA}
    if (data$S3Qual[n] == 0) {data$S3[n] <- NA}


  n <- n+1

}

这就是我想要的,但我希望有一种更有效/简洁的方式(在实际数据框中,这些S / SQual对中有三个以上)。搜索引导我ifelse()apply(),这两者看起来很接近但不太适合我想要的东西,除非我认为错了。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

使用此:

cols <- paste0("S", 1:3)
data[,cols][data[,paste0(cols,"Qual")]==0] <- NA

注意:更改向量1:3以匹配您的实际列数。

答案 1 :(得分:1)

如果你保持简单,我发现理解R代码会更容易。它帮助了我忘记一切的未来。

你可以制作副本,并对任何等于零的项目做一个简单的替换(这是费迪南德所做的......他更聪明):

data1 <- data[,c(2:4)]
data2 <- data[,c(5:7)]
data2[data1==0] <- NA
data[,c(5:7)] <- data2

编辑说明:

前两行创建相等尺寸的数据框。由于它们具有相同的尺寸,因此您可以使用data1中的索引来引用data2

神奇发生在第三行(技术上称为过滤)。如果data1中的元素为0,则返回TRUE,否则返回FALSE。第三行说“如果data1中的元素为0,则从data2返回该索引。”例如,使用上面的示例数据,如果data1[1,2]处的元素为零(它是),则将NA分配给data2[1,2]

最后一行用新的3x3子矩阵替换旧的3x3子矩阵。

答案 2 :(得分:0)

mydata<-mtcars[1:10,1:4]


    mydata
                   mpg cyl  disp  hp
Mazda RX4         21.0   6 160.0 110
Mazda RX4 Wag     21.0   6 160.0 110
Datsun 710        22.8   4 108.0  93
Hornet 4 Drive    21.4   6 258.0 110
Hornet Sportabout 18.7   8 360.0 175
Valiant           18.1   6 225.0 105
Duster 360        14.3   8 360.0 245
Merc 240D         24.4   4 146.7  62
Merc 230          22.8   4 140.8  95
Merc 280          19.2   6 167.6 123

fi<-as.list(names(mydata)[1:2]) # first two columns to be used as base 
se<-as.list(names(mydata)[3:4]) # second two columns which will be replaced based on first two cols
kk<-Map(function(x,y) mydata[[y]]<-ifelse(mydata[[x]]>4,1,mydata[[y]]),fi,se) # for your example replace >4 with `==0` and 1 with NA 
ll<-t(do.call(rbind,kk))
mydata[,3:4]<-ll
  

MYDATA

                  mpg cyl disp hp
Mazda RX4         21.0   6    1  1
Mazda RX4 Wag     21.0   6    1  1
Datsun 710        22.8   4    1 93
Hornet 4 Drive    21.4   6    1  1
Hornet Sportabout 18.7   8    1  1
Valiant           18.1   6    1  1
Duster 360        14.3   8    1  1
Merc 240D         24.4   4    1 62
Merc 230          22.8   4    1 95
Merc 280          19.2   6    1  1

对于您的数据:

fi<-as.list(names(mydata)[1:3]) # first three columns to be used as base 
se<-as.list(names(mydata)[4:6]) # second three columns which will be replaced based on first three cols
kk<-Map(function(x,y) mydata[[y]]<-ifelse(mydata[[x]]==0,NA,mydata[[y]]),fi,se)
ll<-t(do.call(rbind,kk))
mydata[,4:6]<-ll