我得到了一个大数据表,我需要根据列号和依赖行号的索引将单元格设置为固定值(例如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。 由于它是一个庞大的数据表,我正在寻找一种有效的方法来实现此目的
答案 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