我想将矩阵分配给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
对象来解决,但我很好奇这个错误的原因是什么。如果dt1
为data.frame
,则上述语法可行;没有让它与data.table
一起使用的架构理由是什么?
答案 0 :(得分:2)
data.frame
不是matrix
,也不是data.table
和matrix
。 data.frame
和data.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)]