向R中的数据表添加列表列会返回不一致的输出-功能或错误?

时间:2018-07-26 04:31:20

标签: r data.table

我使用this.$ngInit = getTheSessions; ̶c̶o̶n̶s̶t̶ ̶g̶e̶t̶T̶h̶e̶S̶e̶s̶s̶i̶o̶n̶s̶ ̶=̶ ̶(̶)̶ ̶=̶>̶ ̶{̶ function getTheSessions() { adminService.getAllSessions().then((response) => { console.log(response); response.data.forEach(e => e.next_class = e.next_class.substring(0, 10)); $scope.allSessions = response.data; //Other code }); } 向R中的$添加一个列表列。当data.table有多行时,这按预期工作。

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.frame执行相同的操作都会返回预期的输出。

data.frame

3 个答案:

答案 0 :(得分:3)

如果使用双重嵌套的[[<-,则除了确保Andre Elrico's suggestion可以使用list()运算符之外,还可以确保一致行为。这将适用于$<-运算符以及data.table的{​​{1}}赋值运算符。

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> 语法中,data.table的缩写为list()

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

.()

创建相同的结构

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

1行案例

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>

同样,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) 的输出对于两个代码变体都是相同的,并且与2行大小写一致。

str(dt1)

答案 1 :(得分:2)

这是一个奇怪的行为。随时打开有关它的问题。由于此类问题及其静态特性,我还是不喜欢$

对于列表,我喜欢[[]]

得到这样的一致行为:

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

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

答案 2 :(得分:2)

来自vignette("datatable-intro")

  

只要j返回一个 list ,列表中的每个元素都将成为结果 data.table 中的一列。

在您的代码中...

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

list(c(1, 1))被视为j,其第一个元素是长度为2的向量,解释为长度为2的列。由于您的data.table只有一行,因此会产生警告。如Uwe的回答所述,解决此问题的方法是包装一个额外的list(...)

vignette("datatable-reference-semantics")带来了便利功能:

T[, c("colA", "colB", ...) := list(valA, valB, ...)]

# when you have only one column to assign to you
# can drop the quotes and list(), for convenience
DT[, colA := valA]

这适用于您的其他代码...

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

...但是在您发现valA应该创建一个列表列这一特殊情况下,您会分崩离析,因此最好遵循Uwe答案中的建议:始终将多余的{{1 }}或list(...)

另请参阅“ data.frame和data.table之间的较小语法差异是什么?” .(...)中的内容,以了解与数据帧的其他差异。

旁注:如果要像vignette("datatable-faq")这样分配,使用data.table毫无意义。这样做有损软件包的目的,即避免了支持通过引用修改表的语法,即DT$y <- v ...