Как импортировать таблицу Excel в R, чтобы получить двоичные переменные? - PullRequest
4 голосов
/ 19 марта 2019

Мой набор данных выглядит именно так (только с гораздо большим количеством наблюдений и атрибутов): Dataset.xlsx

Я хочу, чтобы у каждого атрибута была двоичная переменная со значением 1, если у PersonX есть, и в противном случае 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

Как вы можете видеть, Person1 и Person3 имеют атрибут: K022K вобщие и Персона1 и Персона2 T593.Есть ли способ как это решить?

Ответы [ 2 ]

5 голосов
/ 19 марта 2019
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

Учтите, что то, что вы пытаетесь сделать, часто называют one-hot encoding или binary encoding.Кроме того, вы можете заметить, что df %>% separate_rows(attribute, sep = "/") ваши данные представлены в аккуратном формате, что может иметь и другие преимущества.

ОБНОВЛЕНИЕ: Чтобы расширить число столбцов, вы можете сначалаопределите, какие атрибуты вы будете кодировать.Итак, что-то вроде select(df, contains("attribute")) или 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>

Но на этом этапе вы можете также рассмотреть пакет рецептов или выполнить поиск по горячим кодам для нескольких переменных.

2 голосов
/ 19 марта 2019

Хорошо, используя ваш пример как minimal.xlsx:

Minimal example CSV

install.packages('readxl')  # if you don't have this already
library(readxl)

example <- read_excel('./minimal.xlsx')  # assuming file is in working directory
example$Attribute <- as.character(example$Attribute)  # convert to character

attrs <- strsplit(example$Attribute, '/')  # split by /
attrs <- unlist(attrs)  # flatten the list
attrs <- unique(attrs)  # extract uniques

for (attr in attrs) {
  attr_row <- grepl(attr, example$Attribute)  # boolean of True/false
  attr_row <- attr_row * 1  # convert to 0, 1
  example[attr] <- attr_row
}

Я пытался объяснить это в комментариях, но по существу:

  • Превратите Атрибуты в персонажей и разделите их по своему символу
  • Объедините их в «набор» вектора уникальных атрибутов
  • Переберите их и сгенерируйте каждую строку
  • Добавить каждую строку обратно в DataFrame

Результат здесь:

Final output

Вы также можете удалить исходный столбец Атрибутов позже, но это должно дать вам то, что вы хотите, является обобщенным решением и не требует внешних библиотек.

Редактировать: Другой ответ короче и определенно использовать его для быстрого решения этой проблемы, лично мне часто нравится использовать базу R, если я могу для небольших задач, как это, особенно для сценариев, которыми я хочу поделиться с другими.

...