有没有办法在 R data.table 中指定当前行

Is there a way to specify the current row in R data.table

下面的代码创建了一个最小的 data.table,显示了我在 for 循环中使用的方法,并打印了所需的输出。

library(data.table)

# example data.table where "ID" corresponds to the row index
df <- data.table(ID = 1:5, parent_ID = c(0,1,1,3,3), value = paste0(rep("S", 5),1:5))

# unsort the rows and remove one so that ID no longer corresponds to the row index
df2 <- df[c(1, 4,5,3), .(ID, parent_ID, value)]

# this method below works
for(i in 2:nrow(df2))
{
  df2[i, "parent_value"] <- df2[which(df2[,ID] %in%  df2$parent_ID[i]), "value"]
}
df2

输出:

   ID parent_ID value parent_value
1:  1         0    S1         <NA>
2:  4         3    S4           S3
3:  5         3    S5           S3
4:  3         1    S3           S1

我的问题是 data.table 中是否有其他方法可以避免 for 循环。我的猜测是它看起来像下面这样,但似乎我需要一种方法来引用当前行,因此是标题问题。


df2[, parent_value := df2[which(df2[,ID] %in% df2$parent_ID[i]), "value"]]

任何想法表示赞赏。

你可以试试这个:

f <- function(b) df[which(df2$ID %in% df2$parent_ID[b$id])]$value
df2[, parent_value:= f(.BY), by=.(id = 1:nrow(df2))]

输出:

   ID parent_ID value parent_value
1:  1         0    S1         <NA>
2:  4         3    S4           S4
3:  5         3    S5           S4
4:  3         1    S3           S1

您也可以使用 .I(如 Severin 在评论中所建议的那样),像这样(magrittr 添加管道只是为了表达清晰:

df2[,id:=.I] %>% 
  .[, parent_value:=df[which(df2$ID %in% df2$parent_ID[id]), value], by=1:nrow(df2)] %>% 
  .[,id:=NULL] %>% 
  .[]

使用match

df2[, parent_value := value[match(parent_ID, ID)]]
   ID parent_ID value parent_value
1:  1         0    S1         <NA>
2:  4         3    S4           S3
3:  5         3    S5           S3
4:  3         1    S3           S1