简单的“for”循环适用于 data.frame 但不适用于 data.table

rns*_*nso 0 r data.table

这与以下问题有关:在给定条件下随机关联两个向量的元素

需要替换“loss”列中比“capitals”数据表同一行中的“capital”条目多的任何条目。损失条目必须从“损失”向量中采样。以下代码在将 Capitals 创建为 data.frame 时有效,但在将其创建为 data.table 时无效:

require(data.table)
capitals<-data.table(capital=c(100,50,25,5))
loss=c(45,10,5,1)

capitals$loss <- sample(loss,replace=F)
capitals
   capital loss
1     100    5
2      50   10
3      25    1
4       5   45


for(i in 1:nrow(capitals)) {
    while(capitals[i,2]>capitals[i,1]){
        capitals[i,2] <- sample(loss, 1)
    }
}
Run Code Online (Sandbox Code Playgroud)

它被困在这里,可能是一个无限循环。以下代码显示它卡在 while 循环中:

for(i in 1:nrow(capitals)) {
    print("in for loop")
    while(capitals[i,2]>capitals[i,1]){
        capitals[i,2] <- sample(loss, 1)
        print("in while loop")
    }
}
[1] "in for loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
[1] "in while loop"
...
Run Code Online (Sandbox Code Playgroud)

原因是什么?如何纠正?谢谢。

wat*_*ova 5

在 R 中,data.table通常充当数据框,但当您在第二个参数中输入数字时则不然。data.table会将该数字视为要评估的函数,因此

capitals[1,2] == 2
Run Code Online (Sandbox Code Playgroud)

capitals[1,1] == 1
Run Code Online (Sandbox Code Playgroud)

capitals[1, (2 + 2)] == 4
Run Code Online (Sandbox Code Playgroud)

在 data.table 中,可以通过不带引号的列名来引用列。

capitals[1, loss]
Run Code Online (Sandbox Code Playgroud)