如何在R中导入Excel表以获取二进制变量?

Tex*_*ime 4 r data-manipulation import-from-excel

我的数据集看起来完全像这样(只有更多的观察值和属性): 数据集

我希望每个属性都有一个二进制变量,如果PersonX拥有它,则值为1,否则为0,但是每个人还必须包括其他人的属性。它应该看起来像这样,当然,如果Person1也具有与Person2相同的属性,则不应再次生成该变量:

ID       Class_Label    A469 T593 K022K A835 Z935 U83F W5326
Person1  TRUE           1    1    1     0    0    0    0
Person2  FALSE          0    1    0     1    1    0    0
Person3  FALSE          0    0    1     0    0    1    1
Run Code Online (Sandbox Code Playgroud)

如您所见,Person1和Person3具有以下属性:公共属性K022K和Person1和Person2 T593。有什么办法解决这个问题吗?

Jas*_*lns 5

library(tidyverse)

df <- tibble(
  id = paste0("Person", 1:3),
  class_label = c(TRUE, FALSE, FALSE),
  attribute = c("A469/T593/K022K", "A835/Z935/T593", "U835F/W5326/K022K")
)
df
#> # A tibble: 3 x 3
#>   id      class_label attribute        
#>   <chr>   <lgl>       <chr>            
#> 1 Person1 TRUE        A469/T593/K022K  
#> 2 Person2 FALSE       A835/Z935/T593   
#> 3 Person3 FALSE       U835F/W5326/K022K

df %>%
  separate_rows(attribute, sep = "/") %>%
  mutate(i = 1) %>%
  spread(attribute, i, fill = 0)
#> # A tibble: 3 x 9
#>   id      class_label  A469  A835 K022K  T593 U835F W5326  Z935
#>   <chr>   <lgl>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Person1 TRUE            1     0     1     1     0     0     0
#> 2 Person2 FALSE           0     1     0     1     0     0     1
#> 3 Person3 FALSE           0     0     1     0     1     1     0
Run Code Online (Sandbox Code Playgroud)

请注意,您尝试执行的操作通常称为one-hot encodingbinary encoding。另外,您可能要注意,df %>% separate_rows(attribute, sep = "/")您的数据采用整洁的格式,可能会有其他好处。

UPDATE: To extend to more columns, you might want to first determine which attributes you will be encoding. So something like, select(df, contains("attribute")) or select(df, 3:4).

df <- tibble(
  id = paste0("Person", 1:3),
  class_label = c(TRUE, FALSE, FALSE),
  attribute = c("A469/T593/K022K", "A835/Z935/T593", "U835F/W5326/K022K"),
  attribute2 = c("one/two/three", "four/five/six", "one/five/six")
)
df
#> # A tibble: 3 x 4
#>   id      class_label attribute         attribute2   
#>   <chr>   <lgl>       <chr>             <chr>        
#> 1 Person1 TRUE        A469/T593/K022K   one/two/three
#> 2 Person2 FALSE       A835/Z935/T593    four/five/six
#> 3 Person3 FALSE       U835F/W5326/K022K one/five/six

one_hot <- function(data, att) {
  quo_att <- enquo(att)
  data %>%
    select(id, class_label, !! quo_att) %>% 
    separate_rows(!! quo_att, sep = "/") %>%
    mutate(i = 1) %>%
    spread(!! quo_att, i, fill = 0) %>%
    select(-id, -class_label)
}


attributes_to_map <- select(df, contains("attribute")) %>% names
attributes_to_map
#> [1] "attribute"  "attribute2"

attributes_to_map %>%
  map_dfc(~ one_hot(df, .)) %>%
  bind_cols(select(df, id, class_label)) %>%
  select(id, class_label, everything())
#> # A tibble: 3 x 15
#>   id    class_label  A469  A835 K022K  T593 U835F W5326  Z935  five  four
#>   <chr> <lgl>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Pers~ TRUE            1     0     1     1     0     0     0     0     0
#> 2 Pers~ FALSE           0     1     0     1     0     0     1     1     1
#> 3 Pers~ FALSE           0     0     1     0     1     1     0     1     0
#> # ... with 4 more variables: one <dbl>, six <dbl>, three <dbl>, two <dbl>
Run Code Online (Sandbox Code Playgroud)

But at this point, you may also want to consider the recipes package or do searches on one-hot encoding for several variables.