※ 引述《clansoda (小笨)》之铭言:
: 各位好 单一变量创造dummy variable网络已经有很多答案了
: 我现在遇到的是要比对多个变量来创造dummy variable
: 假设我的data长下面这样
: rowname a b c
: 1 2 5 NA
: 2 1 NA NA
: 3 1 2 3
: 4 3 NA NA
: 5 2 4 NA
: 6 1 4 5
: 希望能得到
: is.1 is.2 is.3 is.4 is.5
: 1
: FALSE TRUE FALSE FALSE FALSE
: 2
: TRUE FALSE FALSE FALSE FALSE
: 3
: TRUE TRUE TRUE FALSE FALSE
: 4
: FALSE TRUE FALSE TRUE FALSE
: 5
: FALSE TRUE FALSE TRUE FALSE
: 6 TRUE FALSE FALSE TRUE TRUE
: 6
: 这个例子是个简单化的范本
: 一个row有可能分属好几个category 以第一个row举例
: 他就属于第二类跟第五类 第二个row则只属于第一类
: 我现在的写法是
: for (i in 1 : 5) {
: dat[, paste0("is.category", "i") := .SD[, 2 : 4] %in% "i" %>% any,
: by = 1 : nrow(dat)]
: }
: 目前我只会这样写 但是这个方法超慢 以我50万个rows为例就要跑20分钟
: 我相信有更好的写法 只是我不知道如何写 因此想请教各位
用矩阵运算的话,3秒内就可以得到结果了
N <- 500000L
numLvls <- 100L
mat <- matrix(NA, N, numLvls)
# data genertion
system.time({
for (i in 1L:N) {
j <- sort(sample(1L:numLvls, sample(1L:numLvls, 1L)))
mat[i, 1:length(j)] <- j
}
})
# user system elapsed
# 21.13 0.02 21.19
system.time({
idx <- N * (mat - 1L)
idx <- idx[which(!is.na(idx))] + which(!is.na(mat), arr.ind = TRUE)[, 1]
out <- matrix(FALSE, nrow(mat), ncol(mat))
out[idx] <- TRUE
dim(out) <- dim(mat)
})
# user system elapsed
# 2.33 0.39 2.72
library(pipeR)
mat[1, ] %>>% (.[which(!is.na(.))])
# [1] 1 4 6 7 10 12 13 16 18 20 23 24 27 29 31 32 34 38 39 42 43 45 47 49
50 52 54 56 57
# 61 62 66 67 68 69 70 72 74 75 78 80 81 82 86 87 91 97 98 99
which(out[1, ])
# [1] 1 4 6 7 10 12 13 16 18 20 23 24 27 29 31 32 34 38 39 42 43 45 47 49
50 52 54 56 57
# 61 62 66 67 68 69 70 72 74 75 78 80 81 82 86 87 91 97 98 99
for (i in 1L:N)
stopifnot(all.equal(mat[i, ] %>>% (.[which(!is.na(.))]), which(out[i, ])))
# no stop~~~~~
产生资料的时间都已经可以跑七八次了Orz