2015-10-17 80 views
1

問題:在Python中,我會使用字典和使用大量的地圖/應用函數。但是,對於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

在R中,你很少必須自己做虛擬編碼。大多數建模功能爲你做,如果你傳遞給他們一個因子變量。 – Roland

回答

1

我們創建使用model.matrixsplit列創建listlist,最後,串聯的list元件一起(do.call(c,..)一個設計矩陣。

res <- do.call("c",lapply(data, function(x) { 
      x1 <- model.matrix(~0+factor(x)) 
       split(x1, col(x1))})) 

因爲我們只需要前兩個層次,我們可以在「資源」使用​​這將回收到list結束子集。

res[c(TRUE, TRUE, FALSE)] 
#$upper.1 
#[1] 1 1 1 0 0 0 0 0 0 

#$upper.2 
#[1] 0 0 0 1 1 1 0 0 0 

#$country.1 
#[1] 1 0 0 1 0 0 1 0 0 

#$country.2 
#[1] 0 1 0 0 1 0 0 1 0 

#$price.1 
#[1] 1 0 0 0 0 1 0 1 0 

#$price.2 
#[1] 0 1 0 1 0 0 0 0 1 
+0

偉大的解決方案!你能解釋'model.matrix'裏面的部分嗎? – Xiphias

+1

@Xiphias我們使用'9 +'公式來移除攔截列 – akrun

相關問題