高效使用as.numeric()和factor()

5

我从数据库中导入了几百个字符向量到R中,每个向量的长度为6-7百万。它们要么是数值型数据,要么是带有标签(字母)的因子数据 - 所有的因子都有一些NA。例如:

vecA <- c("1",NA, "2",....,NA, "100")
vecB <- c("smith", NA, NA, ... , "jones")

有没有一种有效的方法将vecA强制转换为数字,将vecB强制转换为因子。问题是我不知道数据中数字和因子向量在哪里,一个一个查找很繁琐。


这些向量是在同一个对象中,还是分别为不同的对象?它们有像你示例中那样的常规名称吗? - tim riffe
我将在一个函数中逐个从数据库中调用每个向量。该函数可能会并行化处理。一些字符串中会有特殊字符,但仅限于因子类型数据。 - Yoda
2个回答

7

我会使用tryCatch()函数,首先尝试将每个向量转换为"numeric"类型。如果as.numeric()函数抛出警告信息(当输入向量包含非数字字符时会抛出警告),我将捕获警告并将向量转换为"factor"类型。

vecA <- c("1",NA, "2",NA, "100")
vecB <- c("smith", NA, NA, "jones")

myConverter <- function(X) tryCatch(as.numeric(X), 
                                    warning = function(w) as.factor(X))

myConverter(vecA)
# [1]   1  NA   2  NA 100
myConverter(vecB)
# [1] smith <NA>  <NA>  jones
# Levels: jones smith

1
也许使用正则表达式?对于每个向量,匹配看起来像数字的东西。
convert.numeric <- function(vec) {
  if( grepl("^[0-9]*(\\.[0-9]+)?$",vec)) == !is.na(vec)) ) {
    vec <- as.numeric(vec)
  } else { vec <- as.factor(vec) }
  return(vec)
}

然后将您的向量包装成列表并使用lapply

new.vectors <- lapply(old.vectors,convert.numeric)

1
可能测试前500个元素会更有效率。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接