繁体   English   中英

R将转换应用于data.frame的多列

[英]R apply conversion to multiple columns of data.frame

我想将data.frame中的几列从chr转换为数值,我想在一行中完成。 这是我正在尝试做的事情:

items[,2:4] <- as.numeric(sub("\\$","",items[,2:4]))

但是我收到一个错误消息:

Warning message:
NAs introduced by coercion

如果我按列做它,尽管它起作用:

items[,2:2] <- as.numeric(sub("\\$","",items[,2:2]))
items[,3:3] <- as.numeric(sub("\\$","",items[,3:3]))
items[,4:4] <- as.numeric(sub("\\$","",items[,4:4]))

我在这里想念什么? 为什么要为多列指定此命令? 这是我不知道的奇怪的R特质吗?

示例数据:

Name, Cost1,  Cost2,  Cost3,  Cost4
A,    $10.00, $15.50, $13.20, $45.45
B,    $45.23, $34.23, $34.24, $23.34
C,    $23.43, $45.23, $65.23, $34.23
D,    $76.34, $98.34, $90.34, $45.09

您的问题是, gsub将其x参数转换为character 如果一个listdata.frame实际上是一个list )被转换为character则会发生有线连接:

as.character(list(a=c("1", "1"), b="1"))
# "c(\"1\", \"1\")" "1"

# and "c(\"1\", \"1\")" can not convert into a numeric
as.numeric("c(\"1\", \"1\")")
# NA

一种解决方案是unlist x参数:

items[, 2:5] <- as.numeric(gsub("\\$", "", unlist(items[, 2:5])))

是的,这里有: apply是您要查找的命令:

items<-read.table(text="Name, Cost1,  Cost2,  Cost3,  Cost4
A,    $10.00, $15.50, $13.20, $45.45
B,    $45.23, $34.23, $34.24, $23.34
C,    $23.43, $45.23, $65.23, $34.23
D,    $76.34, $98.34, $90.34, $45.09", header=TRUE,sep=",")

items[,2:4]<-apply(items[,2:4],2,function(x){as.numeric(gsub("\\$","",x))})
items
  Name Cost1 Cost2 Cost3   Cost4
1    A 10.00 15.50 13.20  $45.45
2    B 45.23 34.23 34.24  $23.34
3    C 23.43 45.23 65.23  $34.23
4    D 76.34 98.34 90.34  $45.09

一种更有效的方法是:

items[-1] <- lapply(items[-1], function(x) as.numeric(gsub("$", "", x, fixed = TRUE)))
items
#   Name Cost1 Cost2 Cost3 Cost4
# 1    A 10.00 15.50 13.20 45.45
# 2    B 45.23 34.23 34.24 23.34
# 3    C 23.43 45.23 65.23 34.23
# 4    D 76.34 98.34 90.34 45.09

到目前为止答案的一些基准

fun1 <- function() {
  A[-1] <- lapply(A[-1], function(x) as.numeric(gsub("$", "", x, fixed=TRUE)))
  A
}
fun2 <- function() {
  A[, 2:ncol(A)] <- as.numeric(gsub("\\$", "", unlist(A[, 2:ncol(A)])))
  A
}
fun3 <- function() {
  A[, 2:ncol(A)] <- apply(A[,2:ncol(A)], 2, function(x) { as.numeric(gsub("\\$","",x)) })
  A
}

这是一些示例数据和处理时间

set.seed(1)
A <- data.frame(Name = sample(LETTERS, 10000, TRUE),
                matrix(paste0("$", sample(99, 10000*100, TRUE)), 
                       ncol = 100))
system.time(fun1())
#    user  system elapsed 
#    0.72    0.00    0.72 
system.time(fun2())
#    user  system elapsed 
#    5.84    0.00    5.85 
system.time(fun3())
#    user  system elapsed 
#    4.14    0.00    4.14 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM