我的数据框#N / A中有一些我要转换为NA的值。我正在通过数据框上的lapply尝试看似简单的grepl,但它不起作用。这是一个简单的例子......
a = c("#N/A", "A", "B", "#N/A", "C")
b = c("d", "#N/A", "e", "f", "123")
df = as.data.frame(cbind(a,b))
lapply(df, function(x){x[grepl("#N/A", x)]=NA})
哪个输出:
$a
[1] NA
$b
[1] NA
有人能指出我正确的方向吗?我很感激。
答案 0 :(得分:5)
您的函数需要返回x
作为返回值。
尝试:
lapply(df, function(x){x[grepl("#N/A", x)] <- NA; x})
$a
[1] <NA> A B <NA> C
Levels: #N/A A B C
$b
[1] d <NA> e f 123
Levels: #N/A 123 d e f
但您应该使用gsub
代替grep
:
lapply(df, function(x)gsub("#N/A", NA, x))
$a
[1] NA "A" "B" NA "C"
$b
[1] "d" NA "e" "f" "123"
更好(更灵活,可能更容易维护)的解决方案可能是:
replace <- function(x, ptn="#N/A") ifelse(x %in% ptn, NA, x)
lapply(df, replace)
$a
[1] NA 2 3 NA 4
$b
[1] 3 NA 4 5 2
答案 1 :(得分:1)
您需要返回x,在这种情况下最好使用apply
。最好避免使用data.frame
创建cbind
。
a = c("#N/A", "A", "B", "#N/A", "C")
b = c("d", "#N/A", "e", "f", "123")
df = data.frame(a=a, b=b, stringsAsFactors = FALSE)
str(df)
apply(df, 2, function(x){x[grepl("#N/A", x)] <- NA; return(x)})
答案 2 :(得分:1)
如果您要从CSV /制表符分隔文件中读取此数据,请设置na.strings = "#N/A"
。
read.table("my file.csv", na.strings = "#N/A")
从评论更新:或者na.strings = c("#N/A", "#N/A#N/A")
。
即使您遇到问题中描述的情况,您仍然不需要grepl
。
df <- data.frame(
a = c("#N/A", "A", "B", "#N/A", "C"),
b = c("d", "#N/A", "e", "f", "123")
)
df[] <- lapply(
df,
function(x)
{
x[x == "#N/A"] <- NA
x
}
)
df
## a b
## 1 <NA> d
## 2 A <NA>
## 3 B e
## 4 <NA> f
## 5 C 123
答案 3 :(得分:0)
根据问题中的示例,您不需要任何类型的apply
循环,只需执行
df[df == "#N/A"] <- NA
根据您#N/A#N/A
的情况(虽然您没有提供此类数据),另一种解决方法是
df[sapply(df, function(x) grepl("#N/A", x))] <- NA
在这两种情况下,数据本身都会更新,而只是打印到消费者