2016-09-13 5 views
5

Я заинтересован в том, чтобы взять столбец data.frame, где значения в столбце ограничены в трубе и создают фиктивные переменные из значений, разделенных по каналам.Преобразование столбца с данными, разделенными на тупик, в фиктивные переменные

Например:

Допустим, мы начинаем с

df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim|", "Jim|Steve|Ben")) 

> df 
       a 
1 Ben|Chris|Jim 
2 Ben|Greg|Jim 
3 Jim|Steve|Ben 

Я заинтересован в конечном итоге с:

df2 = data.frame(Ben = c(1, 1, 1), Chris = c(1, 0, 0), Jim = c(1, 1, 1), Greg = c(0, 1, 0), 
       Steve = c(0, 0, 1)) 
> df2 
    Ben Chris Jim Greg Steve 
1 1  1 1 0  0 
2 1  0 1 1  0 
3 1  0 1 0  1 

я не знаю заранее, сколько потенциальных значений есть в поле. В приведенном выше примере переменная «a» может включать 1 значение или 10 значений. Предположим, что это разумное число (т. Е. < 100 возможных значений).

Любые хорошие способы для этого?

ответ

6

Другой способ использует cSplit_e из splitstackshape пакет.

разделение данных по колонке a и fill по 0 и drop оригинальная колонка.

library(splitstackshape) 
cSplit_e(df, "a", "|", type = "character", fill = 0, drop = T) 

# a_Ben a_Chris a_Greg a_Jim a_Steve 
#1  1  1  0  1  0 
#2  1  0  1  1  0 
#3  1  0  0  1  1 
+1

какая отличная находка. –

+1

Много отличных ответов - спасибо всем. Мне нравится, что это лучшее, что кажется самым простым. Благодаря! – dreww2

6

Вот один вариант использования dplyr и tidyr:

library(dplyr) 
library(tidyr) 
df %>% tibble::rownames_to_column(var = "id") %>% 
     mutate(a = strsplit(as.character(a), "\\|")) %>% 
     unnest() %>% table() 

# a 
# id Ben Chris Greg Jim Steve 
# 1 1  1 0 1  0 
# 2 1  0 1 1  0 
# 3 1  0 0 1  1 

Аналог в базе R является:

df$a <- as.character(df$a) 
s <- strsplit(df$a, "|", fixed=TRUE) 
table(id = rep(1:nrow(df), lengths(s)), v = unlist(s)) 

данных:

df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim", "Jim|Steve|Ben")) 
2

Мы можем использовать mtabulate из qdapTools после разделения 'а' столбец

library(qdapTools) 
mtabulate(strsplit(as.character(df$a), "|", fixed = TRUE)) 
# Ben Chris Greg Jim Steve 
#1 1  1 0 1  0 
#2 1  0 1 1  0 
#3 1  0 0 1  1 
0

Вот метод в базовом R

# get unique set of names 
myNames <- unique(unlist(strsplit(as.character(df$a), split="\\|"))) 
# get indicator data.frame 
setNames(data.frame(lapply(myNames, function(i) as.integer(grepl(i, df$a)))), myNames) 

который возвращает

Ben Chris Jim Greg Steve 
1 1  1 1 0  0 
2 1  0 1 1  0 
3 1  0 1 0  1 

первая строка использует strsplit для создания списка имен, разделенных на трубу «|», unlist и unique, создайте вектор уникальных имен. Вторая строка проходит через эти имена с lapply и использует grepl для поиска имен, которые as.integer преобразует в двоичные целые числа. Возвращенный список преобразуется в data.frame и заданные имена столбцов с setNames.