在 data.table 中添加带有 rep 的多个列
Add multiple columns with rep in data.table
我正在尝试使用 rep 函数创建固定数量的列(在本例中为 4 列)。 B 列中提到数字 1 在这些列中应重复的频率。其余列应填入 0。
但我收到错误消息
"Error in rep(1, B) : invalid 'times' argument"
不知道如何解决
test <- data.table(A = c("XYZ", "ZYX", "WER"),
B = c(1, 3, 2))
cols <- LETTERS[3:6]
test[, (cols) := c(rep(1, B), rep(0, length(cols) - B))]
#result should be
result <- data.table(A = c("XYZ", "ZYX", "WER"),
B = c(1, 3, 2),
C = c(1, 1, 1),
D = c(0, 1, 1),
E = c(0, 1, 0),
F = c(0, 0, 0))
这使用了一些非 'data.table' 逻辑,但应该还是很快的:
test[, (cols) := {
D <- diag(length(cols))
D[lower.tri(D)] <- 1
data.table(D[B,])
}]
# A B C D E F
#1: XYZ 1 1 0 0 0
#2: ZYX 3 1 1 1 0
#3: WER 2 1 1 0 0
之所以有效,是因为它创建了一个具有填充对角线和下三角的矩阵,然后使用 test$B
对该矩阵的行进行子集化。
或者,您可以遍历要分配的列的长度序列,并检查该值是否等于或小于:
test[, (cols) := lapply(1:length(cols), function(x) as.numeric(x <= B))]
添加 24 列和 3M 行的一些比较时序:
cols <- LETTERS[-(1:2)]
test <- test[rep(1:3,1e6),]
system.time(test[, (cols) := {
D <- diag(length(cols))
D[lower.tri(D)] <- 1
data.table(D[B,])
}])
# user system elapsed
# 0.937 0.651 1.591
第二次被我击败:
system.time(
test[, (cols) := lapply(1:length(cols), function(x) as.numeric(x <= B))]
)
# user system elapsed
# 0.313 0.132 0.446
我正在尝试使用 rep 函数创建固定数量的列(在本例中为 4 列)。 B 列中提到数字 1 在这些列中应重复的频率。其余列应填入 0。
但我收到错误消息
"Error in rep(1, B) : invalid 'times' argument"
不知道如何解决
test <- data.table(A = c("XYZ", "ZYX", "WER"),
B = c(1, 3, 2))
cols <- LETTERS[3:6]
test[, (cols) := c(rep(1, B), rep(0, length(cols) - B))]
#result should be
result <- data.table(A = c("XYZ", "ZYX", "WER"),
B = c(1, 3, 2),
C = c(1, 1, 1),
D = c(0, 1, 1),
E = c(0, 1, 0),
F = c(0, 0, 0))
这使用了一些非 'data.table' 逻辑,但应该还是很快的:
test[, (cols) := {
D <- diag(length(cols))
D[lower.tri(D)] <- 1
data.table(D[B,])
}]
# A B C D E F
#1: XYZ 1 1 0 0 0
#2: ZYX 3 1 1 1 0
#3: WER 2 1 1 0 0
之所以有效,是因为它创建了一个具有填充对角线和下三角的矩阵,然后使用 test$B
对该矩阵的行进行子集化。
或者,您可以遍历要分配的列的长度序列,并检查该值是否等于或小于:
test[, (cols) := lapply(1:length(cols), function(x) as.numeric(x <= B))]
添加 24 列和 3M 行的一些比较时序:
cols <- LETTERS[-(1:2)]
test <- test[rep(1:3,1e6),]
system.time(test[, (cols) := {
D <- diag(length(cols))
D[lower.tri(D)] <- 1
data.table(D[B,])
}])
# user system elapsed
# 0.937 0.651 1.591
第二次被我击败:
system.time(
test[, (cols) := lapply(1:length(cols), function(x) as.numeric(x <= B))]
)
# user system elapsed
# 0.313 0.132 0.446