如何在数据框中的每一列上使用grepl?

时间:2014-08-19 19:23:08

标签: r

我的数据框#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

有人能指出我正确的方向吗?我很感激。

4 个答案:

答案 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

在这两种情况下,数据本身都会更新,而只是打印到消费者