创建虚拟编码的更有效方法

时间:2015-10-17 10:10:22

标签: r

问题: 在Python中,我会使用dictonaries并使用大量的map / apply函数。但是,对于R,我开始使用这个简单的方法使用列表,我想知道是否有更有效/更优雅的方法来执行以下操作。

在统计中,您使用虚拟变量来表示名义属性的级别。例如,A / B / C将变为00,01,10 .A / B / C / D将变为000,001,010,100。因此,每个项目仅允许一个1。因此,您需要n-1个数字来表示n变量/字母。

这里我创建了一些数据:

data <- data.frame(
  "upper" = c(1,1,1,2,2,2,3,3,3), # var 1
  "country" = c(1,2,3,1,2,3,1,2,3), # var 2
  "price" = c(1,2,3,2,3,1,3,1,2) # var 3
)

创建一个包含键(属性)和值(唯一属性级别列表)的列表:

lst <- list()
for (attribute in colnames(data)) {
  lst[[attribute]] = unique(data[[attribute]])
}

创建虚拟编码,i仅用于考虑n-1个项目:

dummy <- list()
for (attribute in colnames(data)) {
  i <- 1
  for (level in lst[[attribute]]) {
    if (length(lst[[attribute]])!=i) {
      dummy[[paste0(attribute, level)]] <- ifelse(
        data[[attribute]]==level,
        1,
        0
      )
    }
    i <- i + 1
  }
}

结果:

dummy
$upper1
[1] 1 1 1 0 0 0 0 0 0

$upper2
[1] 0 0 0 1 1 1 0 0 0

$country1
[1] 1 0 0 1 0 0 1 0 0

$country2
[1] 0 1 0 0 1 0 0 1 0

$price1
[1] 1 0 0 0 0 1 0 1 0

$price2
[1] 0 1 0 1 0 0 0 0 1

1 个答案:

答案 0 :(得分:1)

我们使用model.matrix创建设计矩阵,split列创建list list,最后将list个元素连接在一起({ {1}})。

do.call(c,..

由于我们只需要前两个级别,因此我们可以对“&#39; res”进行分组。使用res <- do.call("c",lapply(data, function(x) { x1 <- model.matrix(~0+factor(x)) split(x1, col(x1))})) 将回收到c(TRUE, TRUE, FALSE)的末尾。

list