Как создать фиктивные переменные, используя разные столбцы с одинаковыми уровнями - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь получить фиктивные переменные для следующей таблицы:

df:

Value1       var1       var2      var3      var4
9.330154398  HomeATL    AwayHOU   HomeEast  AwayWest
32.43881489  AwaySDN    HomeATL   HomeWest  AwayWest
54.77178387  AwayLAN    HomeATL   AwayEast  HomeSame
54.77178387  AwayLAN    HomeATL   AwayWest  HomeEast

Столбцы var1 и var2 имеют одинаковые уровни. С другой стороны, столбцы var3 и var4 также имеют свои уровни. Поэтому мне нужно, чтобы при создании фиктивных переменных создаваемые новые столбцы не имели повторяющихся уровней. Я имею в виду, что в примере с var3 и var4 для 1-й и 3-й строки оба имеют AwayWest, поэтому мне нужно заполнить только 1 столбец с именем AwayWest числом 1 в каждой строке.

Мой желаемый результат:

Value1  HomeEast    HomeWest    AwayEast    AwayWest    HomeSame    HomeATL AwayHOU AwaySDN AwayLAN
9.330154398 1   0   0   1   0   1   1   0   0
32.43881489 0   1   0   1   0   1   0   1   0
54.77178387 0   0   1   0   1   1   0   0   1
54.77178387 1   0   0   1   0   1   0   0   1

Я попытался создать новый столбец из 1 (col1) для каждого столбца, который нужно преобразовать:

spread(df,var1, col1) %>%
spread(var2, col1)%>%
spread(var3, col1)%>%
spread(var1, col1)

Однако это не работает.

Спасибо

Ответы [ 3 ]

3 голосов
/ 14 мая 2019

Основной вариант R будет использовать model.matrix

df <- cbind(df[, "Value1", drop = F], model.matrix(Value1 ~ . - 1, data = df))
df
#     Value1 var1AwayLAN var1AwaySDN var1HomeATL var2HomeATL var3AwayWest
#1  9.330154           0           0           1           0            0
#2 32.438815           0           1           0           1            0
#3 54.771784           1           0           0           1            0
#4 54.771784           1           0           0           1            1
#  var3HomeEast var3HomeWest var4HomeEast var4HomeSame
#1            1            0            0            0
#2            0            1            0            0
#3            0            0            0            1
#4            0            0            1            0

При необходимости мы можем исправить имена столбцов с помощью

names(df) <- sub("var\\d", "", names(df))

для воспроизведения ожидаемого результата.


Пример данных

df <- read.table(text =
    "Value1       var1       var2      var3      var4
9.330154398  HomeATL    AwayHOU   HomeEast  AwayWest
32.43881489  AwaySDN    HomeATL   HomeWest  AwayWest
54.77178387  AwayLAN    HomeATL   AwayEast  HomeSame
54.77178387  AwayLAN    HomeATL   AwayWest  HomeEast", header = T)
2 голосов
/ 14 мая 2019

A base R опция будет table

tbl <- +(table(c(col(df1[-1])), unlist(df1[-1]) ) > 0)
cbind(df1[1], as.data.frame.matrix(tbl))

Или с использованием tidyverse

library(tidyverse)
rownames_to_column(df1, 'rn') %>%
    gather(key, val, var1:var4) %>% 
    count(rn, val) %>%
    spread(val, n, fill = 0)  %>%
    select(-rn) %>%
    bind_cols(df1[1], .)

data

df1 <- structure(list(Value1 = c(9.330154398, 32.43881489, 54.77178387, 
54.77178387), var1 = c("HomeATL", "AwaySDN", "AwayLAN", "AwayLAN"
), var2 = c("AwayHOU", "HomeATL", "HomeATL", "HomeATL"), var3 = c("HomeEast", 
"HomeWest", "AwayEast", "AwayWest"), var4 = c("AwayWest", "AwayWest", 
"HomeSame", "HomeEast")), class = "data.frame", row.names = c(NA, 
-4L))
0 голосов
/ 14 мая 2019

Вы также можете сделать что-то вроде этого -

   > data.table::setDT(df)[,id:=1:.N]
   > cbind(df[,.(Value1)],dcast(
      melt(setDT(df)[, c(.(id=id), lapply(c("var1","var2","var3","var4"), function(x) paste0(x, get(x))))], id.vars="id"),
      id ~ value,
      length))

Вывод-

     Value1  id var1AwayLAN var1AwaySDN var1HomeATL var2AwayHOU var2HomeATL var3AwayEast var3AwayWest var3HomeEast var3HomeWest
1:  9.330154  1           0           0           1           1           0            0            0            1            0
2: 32.438815  2           0           1           0           0           1            0            0            0            1
3: 54.771784  3           1           0           0           0           1            1            0            0            0
4: 54.771784  4           1           0           0           0           1            0            1            0            0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...