将矩阵分配给data.table的子集

时间:2013-11-12 00:51:29

标签: r data.table

我想将矩阵分配给data.table的多列子集,但矩阵最终会被视为列向量。例如,

dt1 <- data.table(a1=rnorm(5), a2=rnorm(5), a3=rnorm(5))
m1 <- matrix(rnorm(10), ncol=2)
dt1[,c("a1","a2")] <- m1

Warning messages:
1: In `[<-.data.table`(`*tmp*`, , c("a1", "a2"), value = c(-0.308851784175091,  :
  2 column matrix RHS of := will be treated as one vector
2: In `[<-.data.table`(`*tmp*`, , c("a1", "a2"), value = c(-0.308851784175091,  :
  Supplied 10 items to be assigned to 5 items of column 'a1' (5 unused)
3: In `[<-.data.table`(`*tmp*`, , c("a1", "a2"), value = c(-0.308851784175091,  :
  2 column matrix RHS of := will be treated as one vector
4: In `[<-.data.table`(`*tmp*`, , c("a1", "a2"), value = c(-0.308851784175091,  :
  Supplied 10 items to be assigned to 5 items of column 'a2' (5 unused)

问题可以通过首先将m1转换为另一个data.table对象来解决,但我很好奇这个错误的原因是什么。如果dt1data.frame,则上述语法可行;没有让它与data.table一起使用的架构理由是什么?

2 个答案:

答案 0 :(得分:2)

data.frame不是matrix,也不是data.tablematrixdata.framedata.table个对象都是lists。它们的存储方式非常不同,虽然索引可以类似,但这是在引擎盖下处理的。

[<-.data.frame内将矩阵值value拆分为一个列,每列都有一个元素。

(该行为value <- split(value, col(value))))。

另请注意,[<-.data.frame将在将某些内容分配给列的子集的过程中复制整个data.frame。

data.table尝试避免此类复制,因此[<-.data.table应避免<-,因为R中的所有[<-.data.table方法都会进行复制。

如果[<-.data.frame是一个矩阵,则在i内会调用value,但如果只有data.table,则会调用data.table

{{1}}通常希望您明确确保分配时数据类型匹配。这有助于避免任何强制和相关复制。

您可以,或许放入功能请求here以确保兼容性,但鉴于您的使用远远超出建议的范围,那么包作者可能会要求您只使用{{1}}约定和方法

答案 1 :(得分:2)

dt1[,c("a1","a2")] <- as.data.table(m1)

提供了一个简单的解决方案,但确实进行了复制。

@Simon O'Hanlon以data.table的方式提供了一种解决方案:

dt1[ , `:=`( a1 = m1[,1] , a2 = m1[,2] ) ]

我认为@Frank提供了更好的data.table解决方案:

dt1[,c("a1","a2") := as.data.table(m1)]