我经常需要在data.table
中存储复杂的对象,因此我经常使用列表列。有时我需要用空列表初始化该列,有时我需要将一个列表列复制到另一列。
起初,这些似乎没有错:
# the example at https://stackoverflow.com/a/22536321/3718827
dt = data.table(id = 1:2, comment = vector("list", 2L))
# my usage need to add column to existing dt, not creating a data.table from scratch, so I modified it a little bit
dt <- data.table(id = 1:2)
dt[, comment := vector("list", nrow(dt))]
dt[1, comment := .(list(list(a = "a", b = "b")))]
dt[, edited_comment := comment]
但是,如果只有一行,那么上面的代码将不再起作用
> dt <- data.table(id = 1)
> dt[, comment := vector("list", nrow(dt))]
Warning message:
In `[.data.table`(dt, , `:=`(comment, vector("list", nrow(dt)))) :
Adding new column 'comment' then assigning NULL (deleting it).
> dt[1, comment := .(list(list(a = "a", b = "b")))]
> dt[, edited_comment := comment]
Warning message:
In `[.data.table`(dt, , `:=`(edited_comment, comment)) :
Supplied 2 items to be assigned to 1 items of column 'edited_comment' (1 unused)
我尝试了不同的语法,这似乎可行
> dt <- data.table(id = 1)
> dt[, comment := .(list(NULL))]
> dt[1, comment := .(list(list(a = "a", b = "b")))]
> dt[, edited_comment := list(comment)]
对于列表列初始化,也许我发现的示例代码仅用于data.table()
调用。要添加列,则不应使用。
对于复制列,此行为是可以理解的,但是当它与nrow> 1一起工作但与nrow = 1不一起工作时,有点令人惊讶。
我的问题是,该任务的正确语法是什么?
对于第一个版本的nrow> 1 / = 1具有令人惊讶的行为差异,那是预期的行为还是错误?