所以我有一个数据帧,其中一些行具有NA值。我想检测一行是否具有NA值,如果该行是否为NA,则在新列中写出。所以我做了一个标准的双循环来解决它。我的问题是,我可以使用内置R函数更有效吗?我的代码可以工作,但如果我有一个更大的数据框,那么执行此操作将非常繁琐
我的代码:
for (j in 1:ncol(test)) {
for (i in 1:nrow(test)) {
if (is.na(test[i,j])) {
test$NA[i] <- "NA value"
}
else {
test$NA[i] <- "No NA value"
}
}
}
答案 0 :(得分:2)
如果我正确读取了双循环,您希望将数据框中的每一行标记为NA value
,如果NA
在该行中至少出现一次,则标记为No NA value
。您可以在此处使用一些基本R函数来执行此操作,包括rowSums()
和is.na()
:
df <- data.frame(v1=c(1,NA,2), v2=c(1,2,3), v3=c(1,2,NA))
df$nav[rowSums(is.na(df)) == 0] <- "No NA value"
df$nav[rowSums(is.na(df)) > 0] <- "NA value"
> df
v1 v2 v3 nav
1 1 1 1 No NA value
2 NA 2 2 NA value
3 2 3 NA NA value
请注意,我将您的NA
列重命名为nav
,以避免与na
发生冲突,后者在R中具有特殊含义。
答案 1 :(得分:2)
您可以使用apply()
:
set.seed(42)
test <- matrix(sample(c(3:12, NA), 20, repl=TRUE), 5)
test <- as.data.frame(test)
test$`NA` <- c("No NA value", "NA value")[1 + apply(is.na(test), 1, any)]
test
# V1 V2 V3 V4 NA
# 1 NA 8 8 NA NA value
# 2 NA 11 10 NA NA value
# 3 6 4 NA 4 NA value
# 4 12 10 5 8 No NA value
# 5 10 10 8 9 No NA value
命名新列“NA”并不是一个好主意,因为NA
中预定了R
。如果您不需要新列中的标签,则可以使用
test$NAindicator <- apply(is.na(test), 1, any)
您还可以将test
保留为矩阵:
set.seed(42)
test <- matrix(sample(c(3:12, NA), 20, repl=TRUE), 5)
test <- cbind(test, apply(is.na(test), 1, any))
test
# [,1] [,2] [,3] [,4] [,5]
# [1,] NA 8 8 NA 1
# [2,] NA 11 10 NA 1
# [3,] 6 4 NA 4 1
# [4,] 12 10 5 8 0
# [5,] 10 10 8 9 0
或者你可以把它放在一个列表中:
list(mat=test, NAindicator=apply(is.na(test), 1, any))
答案 2 :(得分:0)
以下是Reduce
library(data.table)
setDT(test)[, NAV := c("No NA value", "NA value")[is.na(Reduce(`+`, .SD)) + 1]]
test
# V1 V2 V3 V4 NAV
#1: NA 8 8 NA NA value
#2: NA 11 10 NA NA value
#3: 6 4 NA 4 NA value
#4: 12 10 5 8 No NA value
#5: 10 10 8 9 No NA value
或base R
test$NAV <- paste(sub("\\d+", "No NA", do.call(pmax, test)), "value")
test$NAV
#[1] "NA value" "NA value" "NA value" "No NA value" "No NA value"