2016-11-18 4 views
0

J'essaie de créer plusieurs variables fictives, basées sur une colonne appelée "Tags" dans ma df (2 lignes, 2 colonnes, Tags et Score.) Le problème est que dans chaque cellule de la colonne Tags il peut y avoir un nombre quelconque de valeurs chr (jusqu'à environ 30 valeurs) Je veux créer une nouvelle variable fictive pour chaque valeur chr unique dans une cellule. Cela devrait me dire si un cas a cette valeur spécifique ou . pas (1/0) Pour vous montrer le problème que je suis notamment dput(df):Création de variables fictives à partir de cellules avec plusieurs valeurs de caractères

structure(list(Tags = structure(c(27L, 16L, 4L), .Label = c("\"aan het water\", \"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"er even tussenuit\", \"gebruik streekproducten\", \"iens topper 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", frans, glutenvrij, romantisch, wijnbar, zakelijk", 
"\"aan het water\", \"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"gebruik streekproducten\", \"iens topper 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", glutenvrij, kindvriendelijk, romantisch, wereldkeuken, zakelijk", 
"\"aan het water\", \"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", frans, glutenvrij, romantisch, zakelijk", 
"\"aan het water\", \"biologische gerechten\", \"gebruik streekproducten\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", frans, glutenvrij, romantisch, wijnbar, zakelijk", 
"\"aan het water\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"er even tussenuit\", \"iens topper 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", glutenvrij, grieks, romantisch", 
"\"aan het water\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", italiaans, kindvriendelijk, romantisch, zakelijk", 
"\"aan het water\", \"high tea\", brasserie, frans, kindvriendelijk, romantisch, zakelijk", 
"\"aan het water\", \"high tea\", kindvriendelijk, romantisch, wereldkeuken", 
"\"aan het water\", \"iens topper 2016\", italiaans, kindvriendelijk, romantisch, zakelijk", 
"\"aan het water\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", glutenvrij, kindvriendelijk, romantisch, wereldkeuken, zakelijk", 
"\"aan het water\", \"lactose intolerantie\", frans, glutenvrij, zakelijk", 
"\"aan het water\", frans", "\"all you can eat buffet\", \"er even tussenuit\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", glutenvrij, kindvriendelijk, romantisch, wereldkeuken, zakelijk", 
"\"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"er even tussenuit\", \"gebruik streekproducten\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", glutenvrij, kindvriendelijk, romantisch, wereldkeuken", 
"\"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"gebruik streekproducten\", \"high tea\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", frans, glutenvrij, kindvriendelijk, romantisch, zakelijk", 
"\"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"gebruik streekproducten\", \"iens topper 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", glutenvrij, kindvriendelijk, romantisch, zakelijk", 
"\"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"gebruik streekproducten\", \"lactose intolerantie\", \"met familie\", \"met vrienden\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", chinees, gastronomisch, glutenvrij, kindvriendelijk, romantisch, traditioneel, trendy, verjaardag, zakelijk", 
"\"biologische gerechten\", \"certificaat van uitmuntendheid tripadvisor 2016\", \"vegetarische gerechten\", italiaans, kindvriendelijk", 
"\"biologische gerechten\", \"gebruik streekproducten\", \"iens topper 2016\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", bbq/grill, glutenvrij, kindvriendelijk, romantisch, wijnbar", 
"\"biologische gerechten\", \"gebruik streekproducten\", \"lactose intolerantie\", \"vegetarische gerechten\", glutenvrij, romantisch, wereldkeuken", 
"\"biologische gerechten\", \"gebruik streekproducten\", frans, romantisch", 
"\"certificaat van uitmuntendheid tripadvisor 2016\", \"high tea\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", glutenvrij, romantisch, wereldkeuken, zakelijk", 
"\"er even tussenuit\", \"met familie\", \"met vrienden\", amerikaans, romantisch, trendy, verjaardag, wijnbar, zakelijk", 
"\"gebruik streekproducten\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", \"vegetarische gerechten\", frans, glutenvrij, romantisch, zakelijk", 
"\"high tea\", \"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", frans, glutenvrij, romantisch, zakelijk", 
"\"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", frans, glutenvrij, kindvriendelijk, romantisch, wijnbar, zakelijk", 
"\"lactose intolerantie\", \"noten allergie\", \"pinda allergie\", glutenvrij, kindvriendelijk, spaans", 
"\"lactose intolerantie\", frans, glutenvrij, romantisch, zakelijk", "grieks", "spaans"), class = "factor"), Score = c(8, 9, 8.8)), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"), .Names = c("Tags", 
"Score")) 

et df$Tags[1] me retourne:

[1] "lactose intolerantie", "noten allergie", "pinda allergie", glutenvrij, kindvriendelijk, spaans 
30 Levels: "aan het water", "biologische gerechten", "certificaat van uitmuntendheid tripadvisor 2016", "er even tussenuit", "gebruik streekproducten", "iens topper 2016", "lactose intolerantie", "noten allergie", "pinda allergie", "vegetarische gerechten", frans, glutenvrij, romantisch, wijnbar, zakelijk ... 

je peux manuellement exécutez la commande suivante par exemple, et il fonctionne:

df = mutate(df, lactose_intolerantie = ifelse(grepl("lactose intolerantie", Tags), 1, 0)) 

Il a créé une nouvelle colonne contenant un 1 lorsque la valeur « lactose intolerantie » était présent et zéro quand il est absent.

Je suis à la recherche d'un moyen de faire cela plus rapidement, pour chaque valeur chr possible. J'espère que quelqu'un peut aider. Merci beaucoup d'avoir réfléchi.

+0

Avez-vous une liste de tous les caractères possibles valeurs que vous voulez vérifier? – aosmith

Répondre

1

A deux pas de départ:

x1 = gsub("\"", "",unlist(strsplit(as.character(df$Tags[1]),","))) 
x2 = gsub("\"", "",unlist(strsplit(as.character(df$Tags[2]),","))) 
x3 = gsub("\"", "",unlist(strsplit(as.character(df$Tags[3]),","))) 

# removing only spaces occuring at the start 
x11=gsub("^ ","" ,x1) 
x22=gsub("^ ","" ,x2) 
x33=gsub("^ ","" ,x3) 

# get the unique ones 
x = unique(c(x11,x22,x33)) 

df1 = as.data.frame(lapply(as.list(x), function(x) as.numeric(grepl(x, df$Tags)))) 
colnames(df1) = x 

> df1 
    lactose intolerantie noten allergie pinda allergie glutenvrij kindvriendelijk spaans biologische gerechten 
1     1    1    1   1    1  1      0 
2     1    1    1   1    1  0      1 
3     1    1    1   1    0  0      1 
    certificaat van uitmuntendheid tripadvisor 2016 gebruik streekproducten iens topper 2016 vegetarische gerechten 
1            0      0    0      0 
2            1      1    1      1 
3            0      1    0      1 
    romantisch zakelijk aan het water frans wijnbar 
1   0  0    0  0  0 
2   1  1    0  0  0 
3   1  1    1  1  1 
+0

yup, cela me fait partir! officiellement, j'ai plus de 10 000 lignes dans ma df originale, mais il n'y aura certainement pas plus de 10 000 étiquettes, car il s'agit de restaurants. Génial! –

0

Une possibilité avec dplyr et tidyr, bien que l'utilisation separate_rows signifie que je n'ai pas gardé la colonne d'origine. Vous pouvez vous regrouper en fonction des numéros de ligne ou créer une colonne en double de "Tags" à utiliser pour separate_rows.

S'il n'y a qu'une seule instance d'une étiquette à l'intérieur de chaque cellule:

library(dplyr) 
library(tidyr) 
library(tibble) 

df %>% 
    rownames_to_column() %>% 
    separate_rows(Tags, sep = ", ") %>% 
    mutate(Tags = gsub('"', "", Tags), n = 1) %>% 
    spread(Tags, n, fill = 0) 

J'ai ajouté les noms de ligne à l'ensemble de données, séparés les « Tags » être sur des lignes séparées au lieu d'une seule colonne, supprimé les guillemets supplémentaires autour de certains des noms de balises, puis fait une colonne fictive de 1 pour chaque ligne avant de diffuser dans un format large.

Si chaque ligne peut avoir plusieurs valeurs de l'une des chaînes de caractères:

df %>% 
    rownames_to_column() %>% 
    separate_rows(Tags, sep = ", ") %>% 
    mutate(Tags = gsub('"', "", Tags), n = 1) %>% 
    distinct(rowname, Tags, .keep_all = TRUE) %>% 
    spread(Tags, n, fill = 0)