※ 引述《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