替换数据框中的所有特定值


88

有了数据框,我该如何替换所有行和列中的所有特定值。举例来说,我想用替换所有空记录NA(无需输入位置):

df <- data.frame(list(A=c("", "xyz", "jkl"), B=c(12, "", 100)))

    A   B
1      12
2  xyz    
3  jkl 100

预期结果:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

Answers:


138

像这样:

> df[df==""]<-NA
> df
     A    B
1 <NA>   12
2  xyz <NA>
3  jkl  100

14
有没有一种方法可以有效地实现超过1个值的价值!?
PikkuKatja'3

28
这不适用于因子,df[df=="xyz"]<-"abc"将因“无效因子水平”而出错。有更通用的解决方案吗?
glallen 2015年

1
不为我工作。我尝试了此操作:dfSmallDiscreteCustomSalary [dfSmallDiscreteCustomSalary $ salary ==“ <= 50K”] <-“ 49K”。仍然是唯一的(dfSmallDiscreteCustomSalary $ salary)我得到:[1]> 50K <= 50K
Codious-JR 2015年

3
glallen ...如果您尝试使用已经为因子的新值修改因子列,则可能有更聪明的方法,但我可以建议使用df $ factorcolumn <-as.character( df $ factorcolumn),然后进行修改,最后再次将其重新设置为一个因子... df $ factorcolumn <-as.factor(df $ factorcolumn); 它将与您的新级别和期望值一起完成。
约书亚(Joshua Eric Turcotte),

发现它:df.na.replace(df.columns,Map(“”->“ NA”))。show。有趣的是,我无法将null替换为值。我正在获取:java.lang.IllegalArgumentException:不支持的值类型java.lang.String(空)。在org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble(DataFrameNaFunctions.scala:434)
斯里兰卡

34

由于PikkuKatja和glallen要求更一般的解决方案,而我现在还不能发表评论,因此我将写一个答案。您可以按以下方式组合语句:

> df[df=="" | df==12] <- NA
> df
     A    B
1  <NA> <NA>
2  xyz  <NA>
3  jkl  100

对于因子,zxzak的代码已经产生了因子:

> df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)))
> str(df)
'data.frame':   3 obs. of  2 variables:
 $ A: Factor w/ 3 levels "","jkl","xyz": 1 3 2
 $ B: Factor w/ 3 levels "","100","12": 3 1 2

如果遇到麻烦,我建议暂时删除这些因素。

df[] <- lapply(df, as.character)

18

以下是几个dplyr选项:

library(dplyr)

# all columns:
df %>% 
  mutate_all(~na_if(., ''))

# specific column types:
df %>% 
  mutate_if(is.factor, ~na_if(., ''))

# specific columns:  
df %>% 
  mutate_at(vars(A, B), ~na_if(., ''))

# or:
df %>% 
  mutate(A = replace(A, A == '', NA))

# replace can be used if you want something other than NA:
df %>% 
  mutate(A = as.character(A)) %>% 
  mutate(A = replace(A, A == '', 'used to be empty'))

您将如何使用全列解决方案在整个数据集中用NA替换多个字符串?
茶树

4

我们可以使用data.table快速获取它。首先创建没有因素的df,

df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)), stringsAsFactors=F)

现在您可以使用

setDT(df)
for (jj in 1:ncol(df)) set(df, i = which(df[[jj]]==""), j = jj, v = NA)

您可以将其转换回data.frame

setDF(df)

如果您只想使用data.frame并保留因素,则更加困难,则需要使用

levels(df$value)[levels(df$value)==""] <- NA

其中value是每列的名称。您需要将其插入循环中。


2
为什么要为此用例使用外部库?如果可以用一行解决这个问题,为什么还要循环呢?除了已经存在的答案之外,您的答案如何增加价值?我不打算苛刻,我想我缺少了一些东西,因此提出了问题。
sedot

2
对于大型数据集,这要快得多。它增加了一个替代方案,以便用户可以为他选择最佳产品。
skan

0

如果要替换数据框中的多个值,遍历所有列可能会有所帮助。

假设您要替换""100

na_codes <- c(100, "")
for (i in seq_along(df)) {
    df[[i]][df[[i]] %in% na_codes] <- NA
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.