用数据框列中的其他内容替换 NA 或其他 <NA>

replace NA or else <NA> with something or something else in column of data frame

我已经阅读了一些似乎相关的帖子,但显然我太菜鸟了,无法理解或使任何东西正常工作...

> df
  ID Area Address
1 NA    1    lane
2 11   NA    road
3 12    2    blvd
4 13    5    <NA>

> str(df)
'data.frame':   4 obs. of  3 variables:
 $ ID     : int  NA 11 12 13
 $ Area   : int  1 NA 2 5
 $ Address: Factor w/ 3 levels "blvd","lane",..: 2 3 1 NA

我希望能够——不仅对于上面的数据框,而且对于具有更多行和更多列的更大的数据框——替换我选择的任何列(我通过列名引用)

的所有出现
<NA>

使用我从

中选择的元素
<NA> , NA, "foo", "", 0

当没有

时,执行替换的任何东西都不会中断或出错
<NA>

替换。同样,我想对

执行类似的替换
NA

在我选择的任何列中都没有破损或错误。

如果有技术原因导致我不能按照我的建议去做,那么我可以做些什么来尽可能接近上面的内容(同时坚持使用数据帧——与其他东西来回转换是o.k。如果关于如何准确地管理转换的答案非常明确——并且在某种意义上保留因素,例如,地址列是一个因素,所以在替换之后它仍然应该是一个因素) .

我希望有技术上的原因来说明为什么我不能按照我的建议去做(我很困惑,以至于问不可能的事情),所以我希望在现实允许的情况下尽可能接近,并且一些善良的灵魂将解释我可以在多大程度上接近上述内容,以及如何准确地接近上述内容。

请帮忙(如果没有详细明确的回答,不要以为我能理解)。

谢谢

如果您的数据框像您在问题中显示的那样命名为 df,只需键入:

df[is.na(df)] <- 0

只需确定数据框的名称,如果不是 df,只需将 df 替换为您分配给数据框的名称即可。

如果不生成整个向量字符,则无法将字符串插入到数字或整数向量中,但我们可以插入一个零代替 NA,我们将在下面执行此操作。我们还插入 fill 默认值 "foo" 作为新级别代替 NA 对于问题中显示的那种因素。

1) 查看最后可重复显示的 df.orig 它具有整数和因子列,以下适用于那些以及双精度的数字列。对于数字(双精度和整数),我们分配 0L,以便整数列不会更改为双精度。对于双列,0L 将自动强制加倍。对于具有 NA 值的因子,我们将 NA 添加为最后一个级别,然后将其标签更改为 fill。我们还检查是否有任何 NA 级别,如果有,将它们替换为 fill。人们通常不会发现这两种情况。如果需要转换问题中未显示的其他 类,您将需要扩展下面的代码。

df <- df.orig

# numeric (integer and double)
isNum <- sapply(df, is.numeric)
na2zero <- function(v, ...) replace(v, is.na(v), 0L)
df[isNum] <- lapply(df[isNum], na2zero)

# factor
isFactor <- sapply(df, is.factor)
na2fill <- function(v, fill = "foo", ...) { 
      # handle NA values
      if (any(is.na(v))) {
         v <- addNA(v)
         levels(v)[nlevels(v)] <- fill
      }
      # handle NA levels
      if (any(is.na(levels(v)))) levels[is.na(levels(v))] <- fill
      v 
}
df[isFactor] <- lapply(df[isFactor], na2fill)

给予:

> df
  ID Area Address
1  0    1    lane
2 11    0    road
3 12    2    blvd
4 13    5     foo

2) 或者,我们可以使用 S3 更紧凑地完成它,其中 na2zerona2fill 来自 (1).

rmNA <- function(v, ...) UseMethod("rmNA")
rmNA.numeric <- na2zero
rmNA.factor <- na2fill
rmNA.default <- function(v, ...) v # do not process other classes

df <- df.orig
df[] <- lapply(df, rmNA)

注: df 可重现形式为:

df.orig <- 
structure(list(ID = c(NA, 11L, 12L, 13L), Area = c(1L, NA, 2L, 
5L), Address = structure(c(2L, 3L, 1L, NA), .Label = c("blvd", 
"lane", "road"), class = "factor")), .Names = c("ID", "Area", 
"Address"), class = "data.frame", row.names = c("1", "2", "3", 
"4"))