通过向量索引访问 data.table 列?

Access data.table columns through vector indexes?

我遇到了一个问题,但我在网上找不到满意的答案。我想使用 start:end 向量对 data.frame(也是 data.table 这对我有好处)进行定价。一个例子将阐明我的问题。

假设我有一个像下面这样的data.frame:

df <- data.frame(col_1 = rep(0, 3), col_2 = rep(0, 3), col_3 = rep(0, 3), col_4 = rep(0,3))
df
  col_1 col_2 col_3 col_4
1     0     0     0     0
2     0     0     0     0
3     0     0     0     0

假设我有两个向量:

indexesStart <- c(1, 2, 1)
indexesEnd   <- c(2, 4, 3)

我想将向量逐行指示的范围内的所有值赋值为 1。输出应如下所示:

  col_1 col_2 col_3 col_4
1     1     1     0     0
2     0     1     1     1
3     1     1     1     0

我试过这样的事情:

df[ , indexesStart:indexesEnd] <- 1

但它不起作用,它只需要 indexesStart[1]:indexesEnd[1] 并对所有行重复它。

我必须避免循环,因为我的真实数据框有数百万行,而且速度太慢。感谢任何帮助(data.table 解决方案会更好)

谢谢

这样做就可以了:

df <- data.frame(col_1=rep(0,3),col_2=rep(0,3),col_3=rep(0,3),col_4=rep(0,3))
indexesStart <- c(1, 2, 1)
indexesEnd   <- c(2, 4, 3)

for (i in 1:nrow(df)) df[i, indexesStart[i]:indexesEnd[i]] <- 1

df

这是另一种使用双列矩阵作为索引的技术:

I <- do.call(rbind, lapply(1:length(indexesStart), function(i) cbind(i, indexesStart[i]:indexesEnd[i])))
df[I] <- 1

在第二个变体中,我隐藏了循环(隐藏循环在另一个地方)。

试试这个,它避免了任何循环或 lapply 并且是矢量化的。这利用了 data.frame 实际上是一个列表这一事实。

impute <- function(lst, start, end){ lst[start:end] <- 1; lst }

fill <- function(df, start, end){
  cols <- names(df)
  lst <- as.list(as.data.frame(t(df)))
  res <- as.data.frame(t(Vectorize(impute)(lst, start, end)))
  names(res) <- names(df)
  row.names(res) <- row.names(df)
  res
}

res <- fill(df, indexesStart, indexesEnd)

在我的 MacBook Pro 上执行 100 万行大约需要 5 秒。