如何在R数据框中用NA替换空字符串?

34

我的第一种方法是在从csv文件中读取数据时使用na.strings=""。出于某种原因,这并没有起到作用。我还尝试过:

df[df==''] <- NA

这给了我一个错误:无法使用矩阵或数组进行列索引。

我尝试只选择该列:

df$col[df$col==''] <- NA

这将整个数据框中的每个值都转换为NA,即使除了空字符串之外还有其他值。

然后我尝试使用mutate_all

replace.empty <- function(a) {
    a[a==""] <- NA
}

#dplyr pipe
df %>% mutate_all(funs(replace.empty))

这也会将整个数据框中的每个值都转换为NA。

我怀疑我的“空”字符串有些奇怪,因为第一种方法没有效果,但我无法弄清楚是什么问题。

编辑(根据MKR的请求)dput(head(df))的输出:

structure(c("function (x, df1, df2, ncp, log = FALSE) ", "{",
"    if (missing(ncp)) ", "        .Call(C_df, x, df1, df2, log)",
"    else .Call(C_dnf, x, df1, df2, ncp, log)", "}"), .Dim = c(6L,
1L), .Dimnames = list(c("1", "2", "3", "4", "5", "6"), ""), class = 
"noquote")

我原本以为在函数中设置值并不需要返回,但即使有了返回值,它仍将所有内容更改为NA。是的,我更喜欢在dplyr管道中进行拟合,但即使在函数外部也无法正常工作。编辑:我的评论有点慢,但让我更新一下问题,介绍一些我尝试过的其他方法。 - mp3242
我不确定为什么 df[df==''] <- NA 对于 OP 没有起作用。 - MKR
1
请发布 str(df) - moodymudskipper
@mp3242 你可以直接发布 dput(head(df)) 的输出。 - MKR
1
@MKR请查看我对问题的编辑,以及我对你的答案的评论。 - mp3242
显示剩余3条评论
2个回答

67

我不确定为什么 df[df==""]<-NA 对于OP而言不能正常工作。让我们拿一个样本数据框架来研究一下可选项。

选项#1:基础R

df[df==""]<-NA

df
#    One  Two Three Four
# 1    A    A  <NA>  AAA
# 2 <NA>    B    BA <NA>
# 3    C <NA>    CC  CCC

选项#2:使用dplyr::mutate_allna_if。如果数据框中有多种类型的列,则使用mutate_if

library(dplyr)

mutate_all(df, list(~na_if(.,"")))

或者

#if data frame other types of character Then
df %>% mutate_if(is.character, list(~na_if(.,""))) 

#    One  Two Three Four
# 1    A    A  <NA>  AAA
# 2 <NA>    B    BA <NA>
# 3    C <NA>    CC  CCC

样例数据:

df <- data.frame(One=c("A","","C"), 
                 Two=c("A","B",""), 
                 Three=c("","BA","CC"), 
                 Four=c("AAA","","CCC"), 
                 stringsAsFactors = FALSE)

df
#   One Two Three Four
# 1   A   A        AAA
# 2       B    BA     
# 3   C        CC  CCC

1
第一种方法在出现 OP 所遇到的错误时无法处理 tbl,但是使用 df$col[df$col == ''] <- NA 这个版本似乎可以正常工作。 - user295691
1
我想这是因为我在使用tibbles。虽然细节很小,但很重要。当我暂时改用data.frame()中的数据框并使用上面的选项时,它就可以工作了。 - mp3242
1
@mp3242 我有一个 na_if 调用。此外,正如我在我的答案中提到的那样,如果存在其他类型的列,则可以使用 mutate_if - MKR
1
@MKR 对于字符类型的对象,正确的测试方法是:is.character,而不是is_character。 - GGAnderson
1
@Art:df %>% mutate(across(where(is.numeric), ~ na_if(.x, "")))应该可以工作。 - Rumpl
显示剩余7条评论

13

以下是使用最新的语法(2022年2月)的代码。此版本仅将""值设置为字符列的NA。非常方便,因为较简单的版本会在除字符列之外使用任何内容时抛出错误。

# For character columns only, replace any blank strings with NA values
df <- df %>%
  mutate(across(where(is.character), ~ na_if(.,"")))

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