我的数据集包含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)
使用列索引("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)