Mic*_*ele 19 r data.table
仍然了解这个伟大的包...有谁能解释我这个错误的原因?谢谢!
library(data.table)
DT <- data.table(id = LETTERS,
var1 = rnorm(26),
var2 = rnorm(26))
> DT[2, list(var1, var2)]
var1 var2
1: -0.8628479332 -0.2367492928
> DT[2, c(var1, var2)]
[1] -0.8628479332 -0.2367492928
>
> DT[2, list(var1, var2)] <- DT[8, list(var1, var2)]
Error in `[<-.data.table`(`*tmp*`, 2, list(var1, var2), value = list(var1 = -0.394006912428776, :
object 'var1' not found
> DT[2, c(var1, var2)] <- DT[8, c(var1, var2)]
Error in `[<-.data.table`(`*tmp*`, 2, c(var1, var2), value = c(-0.394006912428776, :
object 'var1' not found
Run Code Online (Sandbox Code Playgroud)
Aru*_*run 35
首先,建议使用:=
而不是[<-
效率.的[<-
主要是提供了一种用于向后一致性.所以,我首先要说明如何有效地使用:=
以获得你所追求的东西.:=
是通过引用分配(它更新data.table而不复制数据,因此非常快).
require(data.table)
DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
Run Code Online (Sandbox Code Playgroud)
假设您要将第二行"y"更改为第五行"y":
DT[2, y := DT[5, y]]
Run Code Online (Sandbox Code Playgroud)
或者等价的
DT[2, `:=`(y = DT[5, y])]
Run Code Online (Sandbox Code Playgroud)
假设你要的第二行改变两个 "Y"和"Z"来表示的相应条目的第5行,则:
DT[2, c("y", "z") := as.list(DT[5, c(y, z)])]
Run Code Online (Sandbox Code Playgroud)
或者等价的
DT[2, `:=`(y = DT[5, y], z = DT[5, z])]
Run Code Online (Sandbox Code Playgroud)
现在只是为了向您展示如何使用[<-
(虽然显然不推荐),它可以按如下方式完成:
DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
DT[1, c("y", "z")] <- as.list(DT[5, c(y, z)])
Run Code Online (Sandbox Code Playgroud)
或者等效地,您也可以传递列号:
DT[1, 2:3] <- as.list(DT[5, c(y, z)])
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
首先,RHS必须是一个列表,[<-data.table
如果它有超过1列要分配.
其次,j
左边的参数<-
不在data.table的环境中进行评估.因此,它需要知道它们的价值j
.既然你提供了(var1
并且没有使它们成为字符向量的双引号),它被理解为变量.因此,它检查变量和,但因为它没有"看到"您的data.table中的列作为变量(比如当你做的RHS分配等一般不会),它会寻找相同父环境中的变量,它是找不到它们的全局环境,因此您得到错误.例如:这样做:var2
var1
var2
<-
y <- "y"
z <- "z"
# And now try your second case:
DT[2, c(y, z)] <- as.list(DT[5, c(y, z)])
# the left side takes values from the assignments you made above
# the right side y and z are evaluated within the environment of your data.table
# and so it sees the columns y and z as variables and their values are picked accordingly
Run Code Online (Sandbox Code Playgroud)
第三,该[<-data.table
函数仅接受参数的atomic
(向量)类型j
.因此,DT[2, list(var1, var2)] <- DT[8, list(var1, var2)]
如果您以正确的方式执行操作,您的第一个作业仍然会出错,即:
y <- "y"
z <- "z"
DT[2, list(y, z)] <- as.list(DT[5, c(y, z)])
# Error in `[<-.data.table`(`*tmp*`, 2, list(y, z), value = list(10L, 15L)) :
# j must be atomic vector, see ?is.atomic
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
[<-
而不当:=
,DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
tracemem(DT)
# [1] "<0x7fbefb89b580>"
DT[1, c("y", "z") := list(100L, 110L)]
tracemem(DT)
# [1] "<0x7fbefb89b580>"
DT[2, c("y", "z")] <- list(200L, 201L)
# tracemem[0x7fbefacc4fa0 -> 0x7fbefd297838]: # copied, inefficient
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25562 次 |
最近记录: |