【问题标题】:Taking a data.table slice with a sequence of (row,col) indices获取具有 (row,col) 索引序列的 data.table 切片
【发布时间】:2018-06-01 01:57:40
【问题描述】:

我有一个类似于下面的data.table

tab <- data.table(a = c(NA, 42190, NA), b = c(42190, 42190, NA), c = c(40570, 42190, NA))
tab
       a     b     c
1:    NA 42190 40570
2: 42190 42190 42190
3:    NA    NA    NA

在指定行索引向量和列索引向量后,我希望返回一个向量,其中包含tab 中与指定的行索引和列索引向量相对应的点。

例如,假设我想获取tab 中的对角线元素。我会指定两个向量,

ri <- 1:3
ci <- 1:3

还有一些函数,function(ri, ci, tab),会返回 tab 的对角线元素。

如果tabdata.frame,我会执行以下操作,

as.data.frame(tab)[cbind(ri, ci)]

但是,我想避免使用data.frame 语法。我还想避免for 循环,因为这往往很慢。

【问题讨论】:

  • 可能会融化成长格式并设置key?
  • 以下是查找具有行向量矩阵的类似问题,列索引:Subsetting a matrix using a vector of indices,Use indices in vector to extract elements from matrix
  • 谢谢@chinsoon12。理想情况下,解决方案将避免转换,而是直接索引。
  • 如果您要处理所有数字数据,最好从一开始就使用matrix。您在矩阵上显示的索引方法非常快。
  • 我会将此命名为 “使用 (row,col) 索引序列获取 DT/矩阵切片”

标签: r indexing data.table matrix-indexing


【解决方案1】:

有一种比强制转换为 matrix 或 data.frame 更快的方法。只需使用[data.frame 函数即可。

`[.data.frame`( tab,  cbind(ri,ci) )
[1]    NA 42190    NA

这是[.data.frame 函数的函数语法。

【讨论】:

  • 太棒了。您能否在回答中解释为什么 [.data.frame 在 data.table 上本地工作,并链接到 its doc
  • R 函数由其第一个参数的类分派。运行class(DT),你会得到[1] "data.table" "data.frame"。由于“[”函数是通用的并且具有数据框方法,即{.data.frame 函数。因此解释器将 data.table 对象传递给该函数的代码,而不是传递给[.data.table。查看methods([) 的输出
【解决方案2】:

(更新:@42- 使用[.data.frame 的答案是最好的。但这是我之前的答案)

as.matrix(tab)[cbind(ri, ci)]

将比melt 更快、更节省内存。

我认为您没有理由不将您的 DT 声明为矩阵,正如@thelatemail 所建议的那样。这是 DT 语法不如矩阵强大的一种情况。

(对于大 DT 的内存效率,data.table 有命令 setDF/setDT 允许在不复制的情况下转换为/从 DF/DT,但我不知道它具有矩阵的等价物。如果这是人们经常做的事情,它可能会对 DT 提出很好的增强请求。

对于非常大的维度,您可能会查看 Matrix's sparse-matrix formats 包),或分块您的数据,或使用磁盘支持的数据结构。)

【讨论】:

  • 当然。矩阵索引是 R imho 中最容易被忽视的功能之一。
  • 谢谢@smci。 tab 派生自 data.table 的一个子集,这就是我不使用矩阵开始的原因。从data.table 到矩阵是否很快?
  • @JoshuaDaly:as.matrix() 应该很快,你的尺寸有多大?如果事情变得非常大,您可能会研究 Matrix 的稀疏矩阵格式,或分块您的数据,或使用磁盘支持的数据结构。
  • 谢谢@smci,幸运的是它不是太大(8 x 4 data.table),但是,我会执行多次操作,所以,我想尽可能地避免开销。但是,您的回答非常好,涵盖了当数据变大时该怎么做,我会将其标记为已回答。
  • 强制是不必要的步骤。将其保留为 data.table(继承自 data.frame)并使用为 data.frames 设计的函数。
猜你喜欢
  • 1970-01-01
  • 2018-12-19
  • 2012-02-24
  • 2022-01-01
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
  • 2023-01-20
  • 2022-01-24
相关资源
最近更新 更多