有没有办法在 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
下面的代码创建了一个最小的 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