r - 检查每一列是否存在缺失值

6

我有一个数据框中的列列表,我想检查所有这些列是否为NA,并创建一个新列告诉我它们是否为NA

以下是使用一列进行操作的示例,其中Any_Flag是我的新列:

ItemStats_2014$Any_Flag <- ifelse(is.na(ItemStats_2014$Item_Flag_A), "Y", "N")

当我尝试在多个列上运行检查时,我得到了我期望的结果:
ItemStats_2014$Any_Flag <- ifelse(all(is.na(ItemStats_2014[ ,grep("Flag", names(ItemStats_2014), value = T)])), "Y", "N")

它会将所有东西都返回为false或“N”。
5个回答

9

数据

set.seed(1)
data <- c(LETTERS, NA)
df <- data.frame(Flag_A = sample(data), Flag_B = sample(data), 
                 C = sample(data), D = sample(data), Flag_E = sample(data))

df <- rbind(NA, df)

代码

识别每行中的所有缺失值:

> df$All_NA <- apply(df[, grep("Flag", names(df))], 1, function(x) all(is.na(x)))
> head(df)
  Flag_A Flag_B    C    D Flag_E All_NA
1   <NA>   <NA> <NA> <NA>   <NA>   TRUE
2      H      K    B    T      Y  FALSE
3      J      W    C    K      P  FALSE
4      O      I    H    I   <NA>  FALSE
5      V      L    M    S      R  FALSE
6      E      N    P    E      I  FALSE

每行至少识别一个NA:

> df$Any_NA <- apply(df[, grep("Flag", names(df))], 1, function(x) anyNA(x))
> head(df)
  Flag_A Flag_B    C    D Flag_E Any_NA
1   <NA>   <NA> <NA> <NA>   <NA>   TRUE
2      H      K    B    T      Y  FALSE
3      J      W    C    K      P  FALSE
4      O      I    H    I   <NA>   TRUE
5      V      L    M    S      R  FALSE
6      E      N    P    E      I  FALSE

这就是我一直在尝试做的事情,但我一直收到这个错误:Error in apply(ItemStats_2014[, grep("Item_Flag", names(ItemStats_2014))], : dim(X) must have a positive length。 - alexb523
你能粘贴 str(ItemStats_2014, list.len = 10) 的输出吗? - Cainã Max Couto-Silva
$ Item_Flag_A : chr NA NA NA NA ... $ Item_Flag_B : chr NA NA NA NA ... $ Item_Flag_C : chr NA NA NA NA ... $ Item_Flag_N : chr NA NA NA NA ... $ Item_Flag_O : chr NA NA NA NA ... $ Item_Flag_P : chr NA NA NA NA ... $ Item_Flag_R : chr "R" NA NA NA ... $ Item_Flag_V : chr NA NA NA NA ... $ Item_Flag_Z : chr NA NA NA NA ... - alexb523
请确保您的对象是数据框或矩阵,而不是列表。您能验证一下吗?str()函数通常会在第一个信息中告诉您这一点,但我在您的粘贴中没有看到。只需查看dim()class()即可... - Cainã Max Couto-Silva
1
str(ItemStats_2014) 类别为‘data.table’和‘data.frame’:共有19435个观测值,151个变量。 - alexb523
显示剩余2条评论

3

我不确定grep部分的作用是什么,但以下是更简单的方法来实现您想要的:

 apply(ItemStats_2014[, 2:10], MARGIN = 1, FUN = function(x) all(is.na(x)))

用你想要检查的列替换2:10

更正:如果你想检测哪些列包含单词“Flag”,而不是硬编码它们的索引--这也更好! - 我喜欢使用stringr软件包处理文本。你可以执行以下操作来选择你的列:

 library(stringr)
 MyCols <- which(str_detect(names(ItemStats_2014), "Flag"))

现在,在上面的apply(...代码中,将2:10替换为MyCols

grep的目的是调用包含“Flag”名称的列。有没有办法将[, 2:10]格式化,以查找名称中带有“flag”的列? - alexb523
这是我在使用apply函数时遇到的错误:Error in apply(ItemStats_2014[, grep("Flag", names(ItemStats_2014))], : dim(X) must have a positive length。 - alexb523

3

而不需要使用任何apply函数,使用data.table的方式是:

library(arsenal)
library(data.table)

# dummy data
set.seed(1)
data = c(LETTERS, NA)
dt = data.table(Flag_A=sample(data), Flag_B = sample(data), C=sample(data), D=sample(data), Flag_E=sample(data))
dt = rbind(NA, dt)

# All-NA/Any-NA check
columns_to_check = names(dt)[grep('Flag', names(dt))]
dt[, AllNA:=allNA(.SD), by=1:nrow(dt), .SDcols = columns_to_check]
dt[, AnyNA:=anyNA(.SD), by=1:nrow(dt), .SDcols = columns_to_check]

2
我认为您正在尝试测试一行(而不是一列)是否至少包含一个NA。
这里有一个数据集。
x = c(1:10, NA)
df = data.frame(A = sample(x), B = sample(x), C = sample(x))

这里有一个循环,测试是否存在anyNA

df$Any_na = apply(df[,2:3], 1, anyNA)
df

    A  B  C Any_na
1  NA  8  9  FALSE
2   5  9 NA   TRUE
3   9  3 10  FALSE
4   7  5  1  FALSE
5   4  2  3  FALSE
6  10  4  6  FALSE
7   3  1  2  FALSE
8   6  6  5  FALSE
9   1 10  7  FALSE
10  2 NA  8   TRUE
11  8  7  4  FALSE

只选取数据集中包含“Flag”列名的部分,而不是整个数据集。 - alexb523

1
这可能有助于您入门:

# Sample dataframe
dfx <- data.frame(
x = c(21L, 21L, 21L, 22L, 22L, NA),
y = c(1449, 1814, 582, 582, 947, 183),
s = c(26.4, 28.7, 32, 25.3, NA, 25.7),
z = c(NA,NA,NA,NA,NA,NA)
)

# Sapply works well here 
ifelse(sapply(dfx, function(x)all(is.na(x))) == TRUE, "Y","N")

输出:
 x   y   s   z 
"N" "N" "N" "Y"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接