简单' for' loop适用于data.frame但不适用于data.table

时间:2014-08-10 05:18:33

标签: r data.table

这与以下问题有关:Randomly associate elements of two vectors given conditions

需要替换'loss'列中任何超过'capitals'Data.table的同一行中'capital'条目的条目。损失条目必须从“损失”向量中抽样。 以下代码在大写字母创建为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)
    }
}

它被卡在这里,可能是一个无限循环。以下代码显示它卡在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"
...

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

2 个答案:

答案 0 :(得分:3)

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

capitals[1,2] == 2

capitals[1,1] == 1

capitals[1, (2 + 2)] == 4

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

capitals[1, loss]

答案 1 :(得分:2)

如果我正确阅读,你需要资金&gt;损失。并且,您想重新抽样那种关系不适合的那些。 waternova是正确的,data.tables表现得有些不同。我可能会在你的鞋子里做这样的事情。 虽然,说实话,我从未写过这样的循环。

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

capitals[,loss:=sample(startloss,replace=F)]
##When there are a positive number of rows where capital < loss, that subset gets replaced.
##Previous iteration took a sample of 1, but we want a sample the same size
##as the number of rows where the condition fails, so we use .N, a special 
##variable available in the data table environment that is the number of 
##rows of a subset.
while(nrow(capitals[capital<loss])>0){  
  capitals[capital<loss, loss:=sample(startloss,.N)]
  print(capitals)
}