data.table:分配一个列值,其中该列由另一列指定

时间:2019-01-24 15:44:12

标签: r data.table

让我们说我是 R 中的下一个 data.table

 test
   a b node_feature_name node_split index node_child_left
1: 0 9                 b        7.5    99              11
2: 1 8                 a        1.5    99              12
3: 2 7                 b        7.5    99              13
4: 4 6                 a        1.5    99              14

我想拥有的是 index 列的 update
根据 node_child_left IF 的值, 由node_feature_name 分配的值小于或等于 <= node_split
(动态)

因此,我想要一些东西:

1: b -> 9 <= 7.5 == False
2: a -> 1 <= 1.5 == True
3: b -> 7 <= 7.5 == True
4: a -> 4 <= 1.5 == False

但是

dt[,index := ifelse( get(node_feature_name) <= node_split, node_child_left, index, by = node_split]

要慢:'( 另外,当我离开时,by语句->

test[,index := ifelse( get(node_feature_name) <= node_split, node_child_left, index)]

然后我没有期望的结果,因为: get(node_feature_name)将代表 node_feature_name 的第一个值的列(因此为b列)

所需结果:

   a b node_feature_name node_split index node_child_left
1: 0 9                 b        7.5    99              11
2: 1 8                 a        1.5    12              12
3: 2 7                 b        7.5    13              13
4: 4 6                 a        1.5    99              14

2 个答案:

答案 0 :(得分:4)

test[, nfeat := .SD[[.BY[[1]]]], by = node_feature_name]
test[nfeat <= node_split, index := node_child_left]

其他创建nfeat的方式:

Data Table - Select Value of Column by Name From Another Column

How to select the columns by the content in another column in data.table of R?

Select values from different columns based on a variable containing column names

我想这不是构造数据(在另一列中引用列名)的一种好方法,但是在不了解更多信息的情况下,我无法真正说出如何最好地对其进行改进。

再提速,我们不知道完整数据是否有更多的列,例如ab或更多的行,因此我将不制作自己的示例数据来进行测试。

答案 1 :(得分:0)

如果我们将'{_1}}从'node_split by更改,则将获得正确的列值,因为'node_split'具有重复的元素

to sequence of rows, the

注意:最好按顺序分组而不是按其他分组,因为总有可能行数大于1


如果它是library(data.table) setDT(test)[, index := if(get(node_feature_name) <= node_split) node_child_left else index , by = seq_len(nrow(test))] test # a b node_feature_name node_split index node_child_left #1: 0 9 b 7.5 99 11 #2: 1 8 a 1.5 12 12 #3: 2 7 b 7.5 13 13 #4: 4 6 a 1.5 99 14 ,则可以使用base R索引来使其更快

row/column

基准

在稍大的数据集上,setDF(test) i1 <- test[1:2][cbind(seq_len(nrow(test)), match(test$node_feature_name, names(test)))] <= test$node_split test$index[i1] <- test$node_child_left[i1] 方法的时间为

base R

test1 <- test[rep(seq_len(nrow(test)), 1e6), ] system.time({ i1 <- test1[1:2][cbind(seq_len(nrow(test1)), match(test1$node_feature_name, names(test1)))] <= test1$node_split test1$index[i1] <- test1$node_child_left[i1] }) #user system elapsed # 0.116 0.020 0.136 的{​​{1}}方法

get

数据

data.table