首页 > 解决方案 > 将列表列添加到 R 中的数据表会返回不一致的输出 - 功能还是错误?

问题描述

我使用$将列表列添加到data.tableR 中的 a。当data.table具有多行时,这将按预期工作。

library(data.table)

dt2 <- data.table(x = 1:2)
dt2$y <- list(c(1, 1), c(2, 2))
dt2
#>    x   y
#> 1: 1 1,1
#> 2: 2 2,2

但是,当data.table恰好有一行时,仅返回列表中向量的第一个元素并带有警告:

dt1 <- data.table(x = 1)
dt1$y <- list(c(1, 1))
#> Warning in `[<-.data.table`(x, j = name, value = value): Supplied 2 items
#> to be assigned to 1 items of column 'y' (1 unused)
dt1
#>    x y
#> 1: 1 1

这似乎不一致。它是一个功能还是一个错误?

相比之下,对data.frames 执行相同操作会返回预期的输出,而不管data.frame.

df1 <- data.frame(x = 1)
df1$y <- list(c(1, 1))
df1
#>   x    y
#> 1 1 1, 1

df2 <- data.frame(x = 1:2)
df2$y <- list(c(1, 1), c(2, 2))
df2
#>   x    y
#> 1 1 1, 1
#> 2 2 2, 2

标签: rdata.table

解决方案


除了Andre Elrico 关于使用[[<-操作符的建议之外,如果使用双嵌套,也可以确保一致list()的行为。这将适用于$<-运算符以及data.table' :=赋值运算符。

2排案例

library(data.table)
dt2 <- data.table(x = 1:2)
dt2$y <- list(list(c(1, 1), c(2, 2)))
str(dt2)

dt2 <- data.table(x = 1:2)
dt2[, y := .(.(c(1, 1), c(2, 2)))]
str(dt2)

在两种变体str(dt2)中返回相同的:

Classes ‘data.table’ and 'data.frame':    2 obs. of  2 variables:
 $ x: int  1 2
 $ y:List of 2
  ..$ : num  1 1
  ..$ : num  2 2
 - attr(*, ".internal.selfref")=<externalptr>

请注意,indata.table语法list()可以缩写为.().

为了比较,这里是 OP 使用的代码

dt2 <- data.table(x = 1:2)
dt2$y <- list(c(1, 1), c(2, 2))
str(dt2)

创建相同的结构

Classes ‘data.table’ and 'data.frame':    2 obs. of  2 variables:
 $ x: int  1 2
 $ y:List of 2
  ..$ : num  1 1
  ..$ : num  2 2
 - attr(*, ".internal.selfref")=<externalptr>

1排案例

dt1 <- data.table(x = 1)
dt1$y <- list(list(c(1, 1)))
str(dt1)

dt1 <- data.table(x = 1)
dt1[, y := .(.(c(1, 1)))]
str(dt1)

同样,两种代码变体的输出str(dt1)相同,也与 2 行情况一致。

Classes ‘data.table’ and 'data.frame':    1 obs. of  2 variables:
 $ x: num 1
 $ y:List of 1
  ..$ : num  1 1
 - attr(*, ".internal.selfref")=<externalptr>

推荐阅读