如果值超出范围,则设置为NA

use*_*292 3 r

我的数据集包含6个字段和4个具有一些NA值的行.

a=c(5,6,7,12)
b=c(7,2,3,4)
c=c(8,8,21)
d=c(1,1)
e=c(1,2,5,9)
f=c(20,3,11)
length(c)=4
length(d)=4
length(f)=4
z=data.frame(a,b,c,d,e,f)


a   b   c   d   e   f
5   7   8   1   1   20
6   2   8   1   2   3
7   3   21  NA  5   11
12  4   NA  NA  9   NA
Run Code Online (Sandbox Code Playgroud)

这是我需要做的:对于字段a,c,d和f,如果值小于6或大于12,那么我需要将其设置为NA.此外,如果该值是alread NA则没有变化(保持NA).

我可以使用ifelse为每个字段做到这一点,但我的数据包含数十个字段,所以我想知道是否有一种有效的方法来做到这一点.

最终的数据是

a   b   c   d   e   f
NA  7   8   NA  1   NA
6   2   8   NA  2   NA
7   3   NA  NA  5   11
12  4   NA  NA  9   NA
Run Code Online (Sandbox Code Playgroud)

akr*_*run 5

使用列索引("V1"),我们子集数据集"Z",改变被TRUE基于所述逻辑条件的元素NA通过is.na.

v1 <- c('a', 'c', 'd', 'f')
is.na(z[v1]) <-  z[v1] < 6 | z[v1] >12
z
#   a b  c  d e  f
#1 NA 7  8 NA 1 NA
#2  6 2  8 NA 2 NA
#3  7 3 NA NA 5 11
#4 12 4 NA NA 9 NA
Run Code Online (Sandbox Code Playgroud)

或者@DavidArenburg建议的更快的方法是

z[v1][z[v1] < 6 | z[v1] > 12] <- NA
Run Code Online (Sandbox Code Playgroud)

或@DavidArenburg的data.table选项.我们将'data.frame'转换为'data.table'(setDT(z)),循环遍历'v1'中指定的列以及set满足条件的元素NA.由于[.data.table避免了开销,因此速度会快得多.

library(data.table)
setDT(z)
for(j in v1){
   set(z, i = which(z[[j]] < 6 | z[[j]] > 12), j = j, value = NA_integer_)
}

z
#   a b  c  d e  f
#1: NA 7  8 NA 1 NA
#2:  6 2  8 NA 2 NA
#3:  7 3 NA NA 5 11
#4: 12 4 NA NA 9 NA
Run Code Online (Sandbox Code Playgroud)

  • 或者`z [indx] [z [indx] <6 | z [indx]> 12] < - NA`,闻起来像是对我的欺骗 (3认同)
  • 如果你已经在它`library(data.table)那也是这个; for(j in indx)set(z,i = which(z [[j]] <6 | z [[j]]> 12),j = j,value = NA_integer_)` (2认同)