【问题标题】:Use data.table set() to convert all columns from integer to numeric使用 data.table set() 将所有列从整数转换为数字
【发布时间】:2015-04-22 07:08:54
【问题描述】:

我正在处理一个有 1900 列和大约 280,000 行的 data.table。

目前,数据完全是“整数”,但我希望它们明确地“数字”,以便稍后将其传递给 bigcor() 函数。显然,bigcor() 只能处理“数字”而不是“整数”。

我试过了:

full.bind <- full.bind[,sapply(full.bind, as.numeric), with=FALSE]

不幸的是,我得到了错误:

Error in `[.data.table`(full.bind, , sapply(full.bind, as.numeric), with = FALSE) : 
  j out of bounds

所以,我尝试使用 data.table set() 函数,但出现错误:

Error in set(full.bind, value = as.numeric(full.bind)) : 
  (list) object cannot be coerced to type 'double'

我创建了一个简单的可重现示例。请记住,实际的列不是“a”、“b”或“c”;它们是极其复杂的列名,因此不可能单独引用列。

dt <- data.table(a=1:10, b=1:10, c=1:10)

所以,我最后的问题是:

1) 为什么我的 sapply 技术不起作用? (什么是“j 越界”错误?) 2) 为什么 set() 技术不行? (为什么不能将 data.table 强制转换为数字?) 3) bigcor() 函数是否需要数字对象,还是有其他问题?

【问题讨论】:

  • 收到答案后不删除问题。你得到了免费的帮助,所以试着感恩。
  • 我实际上试图在发布后立即删除它,因为我在其他地方找到了答案。很抱歉!
  • 不确定data.framedata.table 之间的区别(所以也许这无关紧要,抱歉!),但我发现dplyr 在这里很有帮助:mutate_if(df, is.integer, as.numeric) 将所有整数列转换为数字:干净、简洁、快速。

标签: r data.table


【解决方案1】:

使用.SD 并通过引用分配:

library(data.table)
dt <- data.table(a=1:10, b=1:10, c=1:10)
sapply(dt, class)
#        a         b         c 
#"integer" "integer" "integer"

dt[, names(dt) := lapply(.SD, as.numeric)]
sapply(dt, class)
#        a         b         c 
#"numeric" "numeric" "numeric"

set 仅适用于此处的一列(请注意文档,其中没有说 j 是可选的),因为必须生成每个替换列。如果你想使用它,你需要遍历列(例如,使用for 循环)。它可能更可取,因为它需要更少的内存(额外的内存需要对应于一列,而第一种方法需要整个 data.table 的额外内存)。

for (k in seq_along(dt)) set(dt, j = k, value = as.character(dt[[k]]))
sapply(dt, class)
#         a           b           c 
#"character" "character" "character"

但是,bigcor(来自 package 传播)需要一个矩阵作为输入,而 data.table 不是矩阵。所以,你的问题不是列类型,而是你需要使用as.matrix(dt)

【讨论】:

  • set() 可以同时处理多个列,但无论如何都必须为每一列生成value。但更喜欢您的set() 方法,因为它需要一个额外的双列的内存.. :=lapply() 必须先将每一列转换为数字才能替换(这需要整个数据的大小为双倍)。
  • @Arun 谢谢。我试图将此添加到答案中。但是,我更喜欢第一种方法,因为它的语法更好。我很少遇到没有足够可用内存的情况。
  • 如果你只想改变一些列怎么办?例如,我想排除第三个:dt[, names(.SD) := lapply(.SD, as.numeric), .SDcols=!c(3)] 我得到这个错误:[.data.table(dt 中的错误, , :=(names(.SD), lapply(.SD, as.integer)), := 的 LHS 不是列名(“字符”)或位置(“整数”或“数字”)和dt[, names(dt) := lapply(.SD, as.numeric), .SDcols=!c(3)] 给出另一个错误: In [.data.table(dt, , :=(names(dt), lapply (.SD, as.integer)), : 提供 3 列以分配值列表(长度为 2)(回收剩余 1 个项目)。
  • dt[, names(dt[-3]) := lapply(.SD, as.numeric), .SDcols=!c(3)] 似乎太长了。
猜你喜欢
  • 1970-01-01
  • 2021-11-22
  • 2017-04-21
  • 2013-04-01
  • 2017-02-17
  • 2010-10-21
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多