【发布时间】:2011-03-22 10:14:57
【问题描述】:
我有一个数据框,其中包含(随机位置)一个字符值(比如"foo"),我想用NA 替换它。
在整个数据框中这样做的最佳方法是什么?
【问题讨论】:
-
不要忘记重新定义你的列 as.numeric() 将几个字符从“foo”切换到 NA 不会强制整个集合为数字。你必须强迫它。 (如果这就是你正在做的)
我有一个数据框,其中包含(随机位置)一个字符值(比如"foo"),我想用NA 替换它。
在整个数据框中这样做的最佳方法是什么?
【问题讨论】:
这个:
df[ df == "foo" ] <- NA
【讨论】:
df[ df == NA ] = "foo") 将不起作用;你需要使用df[is.na(df)] <- "foo"
将其扼杀在萌芽状态的一种方法是在您首先读取数据时将该字符转换为 NA。
df <- read.csv("file.csv", na.strings = c("foo", "bar"))
【讨论】:
另一种解决方法如下:
for (i in 1:ncol(DF)){
DF[which(DF[,i]==""),columnIndex]<-"ALL"
FinalData[which(is.na(FinalData[,columnIndex])),columnIndex]<-"ALL"
}
【讨论】:
另一个选项是is.na<-:
is.na(df) <- df == "foo"
请注意,它的使用可能看起来有点违反直觉,但实际上它将 NA 值分配给右侧索引处的df。
【讨论】:
'is.na<-'(df, df=="foo")
这可以通过dplyr::mutate_all() 和replace 完成:
library(dplyr)
df <- data_frame(a = c('foo', 2, 3), b = c(1, 'foo', 3), c = c(1,2,'foobar'), d = c(1, 2, 3))
> df
# A tibble: 3 x 4
a b c d
<chr> <chr> <chr> <dbl>
1 foo 1 1 1
2 2 foo 2 2
3 3 3 foobar 3
df <- mutate_all(df, funs(replace(., .=='foo', NA)))
> df
# A tibble: 3 x 4
a b c d
<chr> <chr> <chr> <dbl>
1 <NA> 1 1 1
2 2 <NA> 2 2
3 3 3 foobar 3
另一个dplyr 选项是:
df <- na_if(df, 'foo')
【讨论】:
使用dplyr::na_if,您可以将特定值替换为NA。在这种情况下,就是"foo"。
library(dplyr)
set.seed(1234)
df <- data.frame(
id = 1:6,
x = sample(c("a", "b", "foo"), 6, replace = T),
y = sample(c("c", "d", "foo"), 6, replace = T),
z = sample(c("e", "f", "foo"), 6, replace = T),
stringsAsFactors = F
)
df
#> id x y z
#> 1 1 a c e
#> 2 2 b c foo
#> 3 3 b d e
#> 4 4 b d foo
#> 5 5 foo foo e
#> 6 6 b d e
na_if(df$x, "foo")
#> [1] "a" "b" "b" "b" NA "b"
如果您需要对多个列执行此操作,您可以通过 mutate 和 across 传递 "foo"(更新为 dplyr v1.0.0+)。
df %>%
mutate(across(c(x, y, z), na_if, "foo"))
#> id x y z
#> 1 1 a c e
#> 2 2 b c <NA>
#> 3 3 b d e
#> 4 4 b d <NA>
#> 5 5 <NA> <NA> e
#> 6 6 b d e
【讨论】:
假设您不知道列名或有大量列要选择,is.character() 可能有用。
df <- data.frame(
id = 1:6,
x = sample(c("a", "b", "foo"), 6, replace = T),
y = sample(c("c", "d", "foo"), 6, replace = T),
z = sample(c("e", "f", "foo"), 6, replace = T),
stringsAsFactors = F
)
df
# id x y z
# 1 1 b d e
# 2 2 a foo foo
# 3 3 a d foo
# 4 4 b foo foo
# 5 5 foo foo e
# 6 6 foo foo f
df %>%
mutate_if(is.character, list(~na_if(., "foo")))
# id x y z
# 1 1 b d e
# 2 2 a <NA> <NA>
# 3 3 a d <NA>
# 4 4 b <NA> <NA>
# 5 5 <NA> <NA> e
# 6 6 <NA> <NA> f
【讨论】: