根据列号和单独的索引向量替换数据表中的值

时间:2019-05-28 09:36:48

标签: r data.table

我得到了一个大数据表,我需要根据列号和依赖行号的索引将单元格设置为固定值(例如0)。

作为一个例子,我得到了一个全为1的数据表'dt'。另外,我有一个列向量,给出应保持不变的列数(每行),其余列应设置为0。

dt <- setnames(data.table(matrix(1,nrow=100, ncol=11)),as.character(c(0:10)))

set.seed(1)
index <- sample(c(0:11),100, replace=TRUE)

> dput(index)
c(3L, 4L, 6L, 10L, 2L, 10L, 11L, 7L, 7L, 0L, 2L, 2L, 8L, 4L, 
9L, 5L, 8L, 11L, 4L, 9L, 11L, 2L, 7L, 1L, 3L, 4L, 0L, 4L, 10L, 
4L, 5L, 7L, 5L, 2L, 9L, 8L, 9L, 1L, 8L, 4L, 9L, 7L, 9L, 6L, 6L, 
9L, 0L, 5L, 8L, 8L, 5L, 10L, 5L, 2L, 0L, 1L, 3L, 6L, 7L, 4L, 
10L, 3L, 5L, 3L, 7L, 3L, 5L, 9L, 1L, 10L, 4L, 10L, 4L, 4L, 5L, 
10L, 10L, 4L, 9L, 11L, 5L, 8L, 4L, 3L, 9L, 2L, 8L, 1L, 2L, 1L, 
2L, 0L, 7L, 10L, 9L, 9L, 5L, 4L, 9L, 7L)

例如,在第一行中,前三个单元格保持不变,而其他单元格设置为0。 由于它是一个庞大的数据表,我正在寻找一种有效的方法来实现此目的

4 个答案:

答案 0 :(得分:2)

为了避免复杂性,我采取了相反的方法,首先将所有1更改为0。然后,将索引中指示的列数更改为1s是一个double for循环:

library(data.table)

dt <- setnames(data.table(matrix(0,nrow=100, ncol=11)),as.character(c(0:10)))

index <- sample(c(0:11),100, replace=TRUE)

for(i in 1:length(index)) {
  if (index[i] > 0) {
    for(j in 1:index[i]) {
      dt[i,j] <- 1
    }
  }
}

答案 1 :(得分:2)

使用Matrix软件包的选项:

library(Matrix)
mat <- as.matrix(dt)
mat * as.matrix(sparseMatrix(
    i=rep(seq_along(index), index),
    j=unlist(sapply(index, seq_len)), 
    x=1))

或使用data.table::set

for (j in seq_along(names(dt)))
    set(dt, which(j>index), j, 0)

答案 2 :(得分:1)

last_col <- names(dt)[ncol(dt)]
for (r in seq_len(nrow(dt))) {
  zero_from <- max(index[r]-1L, 0L)
  set(dt, i = r, j = as.character(zero_from:last_col), value = 0)
}

答案 3 :(得分:0)

由于dt的全为1,因此您可以通过以下方式重新创建整个data.table

library(data.table)

cols <- ncol(dt)
data.table(t(sapply(seq_len(nrow(dt)), function(i) 
                   rep(c(1, 0), c(index[i], cols - index[i])))))


#     V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
# 1:  1  1  1  0  0  0  0  0  0   0   0
# 2:  1  1  1  1  0  0  0  0  0   0   0
# 3:  1  1  1  1  1  1  0  0  0   0   0
# 4:  1  1  1  1  1  1  1  1  1   1   0
# 5:  1  1  0  0  0  0  0  0  0   0   0
# 6:  1  1  1  1  1  1  1  1  1   1   0
# 7:  1  1  1  1  1  1  1  1  1   1   1
# 8:  1  1  1  1  1  1  1  0  0   0   0
# 9:  1  1  1  1  1  1  1  0  0   0   0
#10:  0  0  0  0  0  0  0  0  0   0   0
#....

将其与前10个index值进行比较

index[1:10]
# [1]  3  4  6 10  2 10 11  7  7  0