r中的数字值并处理缺失值

时间:2013-08-23 09:25:51

标签: r

使用示例数据框:

df <- structure(list(
  KY27PHY1 = c("4", "5", "5", "4", "-", "4", "2","3", "5", "-", "4", "3", "3", "5", "5"),
  KY27PHY2 = c("4", "4","4", "4", "-", "5", "2", "3", "5", "-", "5", "3", "3", "5", "5"),
  KY27PHY3 = c("5", "4", "4", "4", "-", "5", "1", "4", "5","-", "4", "3", "3", "5", "5")),
                .Names = c("KY27PHY1", "KY27PHY2","KY27PHY3"),
                row.names = 197:211,
                class = "data.frame")

我一直在使用以下代码将值转换为数字:

df$KY27PHY1<-as.numeric(df$KY27PHY1)
df$KY27PHY2<-as.numeric(df$KY27PHY2)
df$KY27PHY3<-as.numeric(df$KY27PHY3)

由于我在df数据帧中缺少值,因此总是收到警告消息:

Warning message:
NAs introduced by coercion 

我认为这不是问题,但我只是想要一些关于如何改进代码的建议,所以我没有得到这个消息。

另外,我如何一次性完成所有列(由名称指定)?

非常感谢提前。

4 个答案:

答案 0 :(得分:2)

我看到两种可能性:

  1. 不太可能的是你在R中构建了data.frame。然后,只需更改代码以创建整数向量,或者将-替换为NA,这样as.numeric转换不会抱怨。

  2. 您的data.frame越有可能来自R外部,您可能会使用read.tableread.csv函数之一来阅读它。然后,只需将na.strings = "-"添加到您的通话中,R就会知道这些-应被理解为NA。此外,如果这些列中没有其他奇怪的项,则在这些函数内调用的type.convert函数将自动检测这些是完整的整数列,并将其存储为整数。

答案 1 :(得分:1)

data.table非常快,您应该在使用data.frames后立即使用它。对于你的问题:

library(data.table)
dt = as.data.table(df)
dt[,lapply(.SD,as.numeric)]
    KY27PHY1 KY27PHY2 KY27PHY3
 1:        4        4        5
 2:        5        4        4
 3:        5        4        4
 4:        4        4        4
 5:       NA       NA       NA
 6:        4        5        5
 7:        2        2        1
 8:        3        3        4
 9:        5        5        5
10:       NA       NA       NA
11:        4        5        4
12:        3        3        3
13:        3        3        3
14:        5        5        5
15:        5        5        5

当然,您会收到一些警告,因为“ - ”无法转换为数字

答案 2 :(得分:0)

您可以使用sapply一次完成所有这些操作,但最终会得到matrix,因此您必须将as.data.frame换行才能转换回来。警告只是告诉您原始数据中的字符无法与数字匹配,因此被NA替换。在您的情况下,这些字符为"-"。要确保不打印警告,请使用suppressWarnings

suppressWarnings(as.data.frame(sapply(df,as.numeric)))
   KY27PHY1 KY27PHY2 KY27PHY3
1         4        4        5
2         5        4        4
3         5        4        4
4         4        4        4
5        NA       NA       NA
6         4        5        5
7         2        2        1
8         3        3        4
9         5        5        5
10       NA       NA       NA
11        4        5        4
12        3        3        3
13        3        3        3
14        5        5        5
15        5        5        5

答案 3 :(得分:0)

我在一段时间后写了一个小函数来处理data.frame中的某些值为NA并使用type.convert来转换输出,就像使用了{{1}一样指定read.table

这是功能:

na.strings

这里正在使用:

makemeNA <- function(mydf, NAStrings, fixed = TRUE) {
  dfname <- deparse(substitute(mydf))
  if (!isTRUE(fixed)) {
    mydf <- data.frame(lapply(mydf, function(x) gsub(NAStrings, "", x)))
    NAStrings <- ""
  }
  mydf <- data.frame(lapply(mydf, function(x) type.convert(
    as.character(x), na.strings = NAStrings)))
  mydf
}

您可以从makemeNA(df, "-") # KY27PHY1 KY27PHY2 KY27PHY3 # 1 4 4 5 # 2 5 4 4 # 3 5 4 4 # 4 4 4 4 # 5 NA NA NA # 6 4 5 5 # 7 2 2 1 # 8 3 3 4 # 9 5 5 5 # 10 NA NA NA # 11 4 5 4 # 12 3 3 3 # 13 3 3 3 # 14 5 5 5 # 15 5 5 5 看到我们现在有数字输出。

str

str(makemeNA(df, "-")) # 'data.frame': 15 obs. of 3 variables: # $ KY27PHY1: int 4 5 5 4 NA 4 2 3 5 NA ... # $ KY27PHY2: int 4 4 4 4 NA 5 2 3 5 NA ... # $ KY27PHY3: int 5 4 4 4 NA 5 1 4 5 NA ... 一样,na.strings中的NAStrings 复数。在这里,我们将短划线和值“1”放入makemeNA

NA

您还可以使用正则表达式将值设置为str(makemeNA(df, c("-", 1))) # 'data.frame': 15 obs. of 3 variables: # $ KY27PHY1: int 4 5 5 4 NA 4 2 3 5 NA ... # $ KY27PHY2: int 4 4 4 4 NA 5 2 3 5 NA ... # $ KY27PHY3: int 5 4 4 4 NA 5 NA 4 5 NA ... ,如下所示:

NA

将“not”或“ - ”中的任何值设为df1 <- data.frame(A = c(1, 2, "-", "not applicable", 5), B = c("not available", 1, 2, 3, 4), C = c("-", letters[1:4]))

NA