【发布时间】:2019-04-19 19:13:27
【问题描述】:
我正在尝试按组遍历 data.table 以在每个子组内有条件地为每一行分配值。我可以选择我想要的行,但我无法更新我选择的行中感兴趣的变量。
我认为这可能是因为我必须对 data.table 进行两次切片。我正在使用一个名为dt 的data.table,它有group、center、date 和var 列。这里的目标是将非中心记录的var 的值也称为center==0 与center==1 最接近的(就日期差异而言)中心记录。假设i 是行的位置索引,我想根据条件过滤更新记录,然后在子组gp 中搜索date。
dt[group == gp][i, var:= "new value"]
但是当我运行时
dt[group == gp][i, var]
变量var 似乎没有改变,也就是返回"old value"。
其他信息
上面的命令在一个 for 循环中,也许我没有在这里使用最佳实践。如果有人对以下 for 循环分享他/她的意见,我将不胜感激。谢谢。
for( gp in unique(dt$group)){
tmp = dt[group==gp]
for( i in 1:nrow(tmp)){
new_val = tmp[center==1][which.min(abs(tmp[i, date]-tmp[center==1, date]),var]
dt[group == gp][i, var:= new_val]
}
}
我知道 data.table 中的 set 和 .by。但我不知道如何使用dt[, j=somefunction ,by=group] 语法轻松地将条件搜索功能应用于每个子组。也许我可以在.SD 上放一个 sapply,但它比 for 循环快得多吗?性能的提升是否值得可读性的损失?
编辑
在下面的评论部分,我发现了在 data.table 中同时结合逻辑和位置索引的技巧:
dt[which(group == gp)[i], var := new_val]
关于使用 for 循环是否是个好主意的问题仍未得到解答。任何输入将不胜感激!
示例
假设原始 dt(按组和日期排序)如下所示:
group center date var
1 0 10-01 NA
1 1 10-02 val1
1 0 10-03 NA
1 1 11-05 val2
2 1 10-02 val3
我希望更新后的 dt 是:
group center date var
1 0 10-01 val1
1 1 10-02 val1
1 0 10-03 val1
1 1 11-05 val2
2 1 10-02 val3
假设我们这里有大约 10,000 个组,每个组最多可以有 1000 行。
【问题讨论】:
-
@IceCreamToucan 感谢您的评论!这招奏效了哈哈。
-
@markus 示例为问题的第二部分更新。
标签: r indexing data.table