簡體   English   中英

tidyverse r 中的虛擬代碼分類/有序變量

[英]Dummy code categorical / ordinal variables in the tidyverse r

假設我有一個小標題。

library(tidyverse) 
tib <- as.tibble(list(record = c(1:10), 
                      gender = as.factor(sample(c("M", "F"), 10, replace = TRUE)), 
                      like_product = as.factor(sample(1:5, 10, replace = TRUE)))
tib

    # A tibble: 10 x 3
   record gender like_product
    <int> <fctr>       <fctr>
 1      1      F            2
 2      2      M            1
 3      3      M            2
 4      4      F            3
 5      5      F            4
 6      6      M            2
 7      7      F            4
 8      8      M            4
 9      9      F            4
10     10      M            5

我想用 1 和 0 對我的數據進行虛擬編碼,以便數據看起來或多或少像這樣。

# A tibble: 10 x 8
   record gender_M gender_F like_product_1 like_product_2 like_product_3 like_product_4 like_product_5
    <int>    <dbl>    <dbl>          <dbl>          <dbl>          <dbl>          <dbl>          <dbl>
 1      1        0        1              0              0              1              0              0
 2      2        0        1              0              0              0              0              0
 3      3        0        1              0              1              0              0              0
 4      4        0        1              1              0              0              0              0
 5      5        1        0              0              0              0              0              0
 6      6        0        1              0              0              0              0              0
 7      7        0        1              0              0              0              0              0
 8      8        0        1              0              1              0              0              0
 9      9        1        0              0              0              0              0              0
10     10        1        0              0              0              0              0              1

我的工作流程需要我知道虛擬代碼的一系列變量(即, gender:like_product ),但不想手動識別每個變量(可能有數百個變量)。 同樣,我不想將每個變量的每個級別/唯一值標識為虛擬代碼。 我最終正在尋找一個tidyverse解決方案。

我知道有幾種方法可以做到這一點,但沒有一個完全適合 tidyverse。 我知道我可以使用 mutate...

tib %>%
     mutate(gender_M = ifelse(gender == "M", 1, 0), 
            gender_F = ifelse(gender == "F", 1, 0), 
            like_product_1 = ifelse(like_product == 1, 1, 0), 
            like_product_2 = ifelse(like_product == 2, 1, 0), 
            like_product_3 = ifelse(like_product == 3, 1, 0), 
            like_product_4 = ifelse(like_product == 4, 1, 0), 
            like_product_5 = ifelse(like_product == 5, 1, 0)) %>%
     select(-gender, -like_product)

但這會打破我需要指定每個虛擬編碼 output 的工作流程規則。

我過去曾使用 model.matrix 完成此操作,來自stats package。

model.matrix(~ gender + like_product, tib) 

簡單明了,但我想要 tidyverse 中的解決方案。 編輯:原因是,我仍然必須指定每個變量,並且能夠使用 select 助手來指定諸如gender:like_product之類的東西會更受歡迎。

我認為解決方案是purrr

library(purrr)
dummy_code <- function(x) {
     lvls <- levels(x)
     sapply(lvls, function(y) as.integer(x == y)) %>% as.tibble
} 

tib %>%
     map_at(c("gender", "like_product"), dummy_code)

$record
 [1]  1  2  3  4  5  6  7  8  9 10

$gender
# A tibble: 10 x 2
       F     M
   <int> <int>
 1     1     0
 2     0     1
 3     0     1
 4     1     0
 5     1     0
 6     0     1
 7     1     0
 8     0     1
 9     1     0
10     0     1

$like_product
# A tibble: 10 x 5
     `1`   `2`   `3`   `4`   `5`
   <int> <int> <int> <int> <int>
 1     0     1     0     0     0
 2     1     0     0     0     0
 3     0     1     0     0     0
 4     0     0     1     0     0
 5     0     0     0     1     0
 6     0     1     0     0     0
 7     0     0     0     1     0
 8     0     0     0     1     0
 9     0     0     0     1     0
10     0     0     0     0     1

這種嘗試會產生一個 tibble 列表,但排除的變量record除外,並且我未能將它們全部組合回一個 tibble。 此外,我仍然必須指定每一列,總的來說它看起來很笨重。

有更好的想法嗎? 謝謝!!

model.matrix的替代model.matrix是使用軟件包recipes 這項工作仍在進行中,尚未包含在tidyverse中。 在某個時候它可能會/將被包含在tidyverse軟件包中

我將留給您閱讀食譜,但是在step_dummy步驟中,您可以使用tidyselect軟件包(安裝了recipes )中的特殊選擇器,例如可以在dplyr使用的選擇器starts_with() 我創建了一個小示例來顯示步驟。

下面的示例代碼。

但是,如果這樣比較方便,那么我將由您決定,因為評論中已經指出了這一點。 函數bake()使用model.matrix創建假人。 區別主要在於列名,當然也包括所有單獨步驟的基礎代碼中進行的內部檢查。

library(recipes)
library(tibble)

tib <- as.tibble(list(record = c(1:10), 
                      gender = as.factor(sample(c("M", "F"), 10, replace = TRUE)), 
                      like_product = as.factor(sample(1:5, 10, replace = TRUE))))

dum <- tib %>% 
  recipe(~ .) %>% 
  step_dummy(gender, like_product) %>% 
  prep(training = tib) %>% 
  bake(newdata = tib)

dum

# A tibble: 10 x 6
   record gender_M like_product_X2 like_product_X3 like_product_X4 like_product_X5
    <int>    <dbl>           <dbl>           <dbl>           <dbl>           <dbl>
 1      1       1.              1.              0.              0.              0.
 2      2       1.              1.              0.              0.              0.
 3      3       1.              1.              0.              0.              0.
 4      4       0.              0.              1.              0.              0.
 5      5       0.              0.              0.              0.              0.
 6      6       0.              1.              0.              0.              0.
 7      7       0.              1.              0.              0.              0.
 8      8       0.              0.              0.              1.              0.
 9      9       0.              0.              0.              0.              1.
10     10       1.              0.              0.              0.              0.

如果你不想加載任何額外的包,你也可以像這樣使用 pivot_wider 語句:

tib %>% 
  mutate(dummy = 1) %>% 
  pivot_wider(names_from = gender, values_from = dummy, values_fill = 0) %>%
  mutate(dummy = 1) %>% 
  pivot_wider(names_from = like_product, values_from = dummy, values_fill = 0, names_glue = "like_product_{like_product}")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM