使用data.table set()将所有列从整数转换为数字

Pab*_*ell 5 r data.table

我正在使用一个包含1900列和大约280,000行的data.table.

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

我试过了:

full.bind <- full.bind[,sapply(full.bind, as.numeric), with=FALSE]
Run Code Online (Sandbox Code Playgroud)

不幸的是,我收到错误:

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

所以,我尝试使用data.table set()函数,但是我得到了错误:

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

我创建了一个简单的可重现的例子.请记住,实际列不是"a","b"或"c"; 它们是非常复杂的列名,因此不可能单独引用列.

dt <- data.table(a=1:10, b=1:10, c=1:10)
Run Code Online (Sandbox Code Playgroud)

所以,我最后的问题是:

1)为什么我的sapply技术不起作用?(什么是"j out of bounds"错误?)2)为什么set()技术不是?(为什么data.table不能被强制转换为数字?)3)bigcor()函数是否需要数字对象,还是存在其他问题?

Rol*_*and 18

.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"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

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

  • `set()` 可以同时处理多个列,但是无论如何都必须为每一列生成 `value` .. 但更喜欢您的 `set()` 方法,因为它需要值得一个额外双列的内存.. :=` 和 `lapply()` 必须在替换之前首先将每一列转换为数字(这需要整个数据的大小为双精度)。 (2认同)