2016-06-17 9 views
12

Mam tabelę zawierającą dane filmów, aw ostatniej kolumnie są to kategorie, do których należy film.R- Konwertuj kolumnę list na różne kolumny, używając ich wartości jako nazwy (atrapa).

movieId        title     category 
     1     Toy Story (1995) Animation|Children|Comedy 
     2      Jumanji (1995) Adventure|Children|Fantasy 
     3   Grumpier Old Men (1995)    Comedy|Romance 
     4   Waiting to Exhale (1995)    Comedy|Drama 
     5 Father of the Bride Part II (1995)      Comedy 
     6      Heat (1995)  Action|Crime|Thriller 

Chcę utworzyć jedną kolumnę dla każdej kategorii i umieścić 1, jeśli została zapisana na liście dla tego filmu i zero, jeśli nie. Coś jak:

movieId title animation comedy drama 
1  xx  1   0  1 
2  xy  1   0  0 
3  yy  1   1  0 

tej pory mam tylko przekształcone ciąg do listy z:

f<-function(x) {strsplit(x, split='|', fixed=TRUE)} 
movies2$m<-lapply(movies2$category, f) 

Ale nie wiem, jak to zrobić resztę.

Myślałem o słownikach Python. Ale nie wiem jak to zrobić w R.

danych

df1 <- read.table(header = TRUE, stringsAsFactors = FALSE, 
        text = " movieId        title     category 
        1     'Toy Story (1995)' Animation|Children|Comedy 
        2      'Jumanji (1995)' Adventure|Children|Fantasy 
        3   'Grumpier Old Men (1995)'    Comedy|Romance 
        4   'Waiting to Exhale (1995)'    Comedy|Drama 
        5 'Father of the Bride Part II (1995)'      Comedy 
        6      'Heat (1995)'  Action|Crime|Thriller") 

Odpowiedz

5

Możemy użyć mtabulate z qdapTools po rozcięciu

library(qdapTools) 
cbind(df1[-3],mtabulate(strsplit(df1$category, "[|]"))) 
# movieId        title Action Adventure Animation Children Comedy Crime Drama Fantasy Romance Thriller 
#1  1     Toy Story (1995)  0   0   1  1  1  0  0  0  0  0 
#2  2      Jumanji (1995)  0   1   0  1  0  0  0  1  0  0 
#3  3   Grumpier Old Men (1995)  0   0   0  0  1  0  0  0  1  0 
#4  4   Waiting to Exhale (1995)  0   0   0  0  1  0  1  0  0  0 
#5  5 Father of the Bride Part II (1995)  0   0   0  0  1  0  0  0  0  0 
#6  6      Heat (1995)  1   0   0  0  0  1  0  0  0  1 

lub używając base R

cbind(df1[-3], as.data.frame.matrix(table(stack(setNames(strsplit(df1$category, 
          "[|]"), df1$movieId))[2:1]))) 
4

Oto podstawowa możliwość R, która używa strsplit() do podziału wartości kolumn, a następnie grepl(), aby je dopasować w vapply(). Chodzi o to, aby użyć FUN.VALUE = integer(.) w vapply(), aby wynik w postaci grepl() został magicznie przekonwertowany na liczbę całkowitą.

## split the 'category' column on '|' 
s <- strsplit(df$category, "|", fixed = TRUE) 
## run the unique sorted values through grepl(), getting integer result 
newPart <- vapply(sort(unique(unlist(s))), grepl, integer(nrow(df)), df$category, fixed = TRUE) 
## bind result to other columns 
cbind(df[-3], newPart) 

Rezultatem jest następująca ramka danych.

movieId        title Action Adventure Animation Children Comedy Crime Drama Fantasy Romance Thriller 
1  1     Toy Story (1995)  0   0   1  1  1  0  0  0  0  0 
2  2      Jumanji (1995)  0   1   0  1  0  0  0  1  0  0 
3  3   Grumpier Old Men (1995)  0   0   0  0  1  0  0  0  1  0 
4  4   Waiting to Exhale (1995)  0   0   0  0  1  0  1  0  0  0 
5  5 Father of the Bride Part II (1995)  0   0   0  0  1  0  0  0  0  0 
6  6      Heat (1995)  1   0   0  0  0  1  0  0  0  1 
3

hadleyverse podejście:

library(dplyr) 
library(tidyr) 
library(reshape2) 
library(stringr) 

max.categories = max(str_count(df1$category, "\\|")) + 1 

df1new = df1 %>% separate(category, into=letters[1:max.categories], sep="\\|") %>% 
    melt(c("movieId","title")) %>% 
    filter(!is.na(value)) %>% 
    dcast(movieId + title ~ value, fun.aggregate=length) 
movieId        title Action Adventure Animation Children Comedy Crime Drama Fantasy Romance Thriller 
1  1     Toy Story (1995)  0   0   1  1  1  0  0  0  0  0 
2  2      Jumanji (1995)  0   1   0  1  0  0  0  1  0  0 
3  3   Grumpier Old Men (1995)  0   0   0  0  1  0  0  0  1  0 
4  4   Waiting to Exhale (1995)  0   0   0  0  1  0  1  0  0  0 
5  5 Father of the Bride Part II (1995)  0   0   0  0  1  0  0  0  0  0 
6  6      Heat (1995)  1   0   0  0  0  1  0  0  0  1 

max.categories właśnie sposób programowo zapewnić, że into wektor jest co najmniej tak długo, jak maksymalna liczba kategorii dla danego title. Jeśli już wiesz, że ta wartość nigdy nie jest większa niż, powiedzmy 5, możesz po prostu zrobić, na przykład, into=letters[1:5].