열을 R의 이진 인코딩 열로 변환

Sep 02 2020

정수 (서 수가 아님)로 인코딩 된 명목 변수가 있는데,이 변수를 이진으로 인코딩하고 싶습니다 (더 미나 핫이 아님!). 다음 코드는 내가 찾은 다른 코드에서 수정 한 것입니다. 이것이 유효하고 확장 가능한 접근 방식입니까? 감사!

library(binaryLogic)

df <- data.frame(x1 = c(1, 1, 2, 3), x2 = c(1, 2, 3, 4))

encode_binary <- function(x, name = "binary_") {
    x2 <- as.binary(x)
    maxlen <- max(sapply(x2, length))
    x2 <- lapply(x2, function(y) {
        l <- length(y)
        if (l < maxlen) {
            y <- c(rep(0, (maxlen - l)), y)
        }
        y
    })
    d <- as.data.frame(t(as.data.frame(x2)))
    rownames(d) <- NULL
    colnames(d) <- paste0(name, 1:maxlen)
    d
}

df <- cbind(df, encode_binary(df[["x1"]], name = "binary_x1_"))
df <- cbind(df, encode_binary(df[["x2"]], name = "binary_x2_"))

df

답변

1 minem Sep 02 2020 at 15:23

더 큰 벡터에서 테스트하면 접근 방식이 매우 느립니다.

test_vec <- 1:1e5
system.time(v1 <- encode_binary(test_vec, name = "binary_x1_"))
#  user  system elapsed 
# 22.23    0.08   22.37 

이 SO 질문을 기반으로 훨씬 빠르게 수행되는 코드를 작성했습니다.

encode_binary2 <- function(x, name = "binary_") {
  m <- sapply(x, function(x) rev(as.integer(intToBits(x))))
  tm <- t(m)
  # remove empty bit cols
  i <- which(colSums(tm) != 0L)[1]
  tm <- tm[, i:ncol(tm)]
  # save to data.frame
  d <- as.data.frame(tm)
  rownames(d) <- NULL
  colnames(d) <- paste0(name, 1:ncol(d))
  d
}

system.time(v2 <- encode_binary2(test_vec, name = "binary_x1_"))
# user  system elapsed 
# 0.61    0.02    0.63 

# test that results are equal:
all.equal(v1, v2)
# [1] TRUE