0

一些样本数据:

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()and apply(),这两者看起来很接近,但不太适合我想要的东西,除非我想错了。

有任何想法吗?

4

3 回答 3

2

用这个:

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

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

于 2013-09-05T19:15:52.067 回答
1

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

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

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

编辑解释:

前两行创建等维数据框。因为它们具有相同的维度,您可以使用索引 fromdata1来引用data2

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

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

于 2013-09-05T19:22:13.303 回答
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

我的数据

                  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
于 2013-09-05T19:19:55.687 回答