我发现data.table以下两个操作的逻辑不一致:
操作1:
df1<-data.table(a=c(1,2))
list1<-list(c(1,2), 1)
df1[,b:=list1]
#> df1
# a b
#1: 1 1,2
#2: 2 1
Run Code Online (Sandbox Code Playgroud)
操作2 :( data.table将单例列表视为提供向量)
df2<-data.table(a=c(1))
list2<-list(c(1,2))
df2[, b:=list2]
#Warning message:
#In `[.data.table`(df2, , `:=`(b, list2)) :
# Supplied 2 items to be assigned to 1 items of column 'b' (1 unused)
#> df2
a b
#1: 1 1
Run Code Online (Sandbox Code Playgroud)
我想在第二种情况下的输出是:
# a b
#1: 1 1,2
Run Code Online (Sandbox Code Playgroud)
我可以做到统一两种情况:
df1[, b:=list(list1)]
df2[, b:=list(list2)]
Run Code Online (Sandbox Code Playgroud)
这是最好的解决方案吗?data.table没有选项可以不删除单例列表吗?在我使用的第一种情况下,是否没有额外的操作性能b:=list(list1)?
从/sf/answers/3835854011/
复制我的答案
,我不能建议重复,因为“这个问题没有被赞成或接受的答案”。
这是一个很好的问题,涉及到关于:=操作员的设计决策。
对于使用:=运算符的简单调用,例如col := val,我们决定自动包装val到列表中。做出此决定是为了让用户更方便地分配单列。
当您使用函数调用形式时,":="(col = val)我们不再包装val到列表中。它已经是扩展形式了。:=充当 的别名,list但就地更新。:=您始终可以通过更改为list(或.)之类来检查将更新的列.(col = val)。
并不是说即使作为:=操作员使用,您仍然必须提供 RHS 作为您正在创建 2 个以上列的列表c("col1","col2") := list(val1, val2)。