从具有多个字符值的单元格创建虚拟变量

时间:2016-11-18 19:56:39

标签: r dplyr dummy-variable chr

我正在尝试创建多个虚拟变量,基于我的df中的一个名为“Tags”的列(2行,2列,TagsScore。问题在于每个单元格列Tags中可以有任意数量的chr值(最多约30个值)。我想为一个单元格中的每个唯一chr值创建一个新的虚拟变量。这应该告诉我一个案例是否有是否具体值(1/0)。为了向您显示问题,我要包括dput(df)

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")) 

df$Tags[1]给我回复:

[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 ...  

手动我可以运行以下示例,它可以工作:

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

当“乳糖不耐症”值存在时,它创建了一个包含1的新列,当它不存在时,它创建了零。

我正在寻找一种方法,可以更快地完成每个可能的chr值。希望有人能提供帮助。非常感谢你给出了一个想法。

2 个答案:

答案 0 :(得分:1)

只是一个开始步骤:

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

答案 1 :(得分:0)

使用 dplyr tidyr 的可能性,尽管使用separate_rows意味着我没有保留原始列。您可以根据行号重新加入,或者制作一个“标签”的重复列,用于separate_rows

如果每个单元格中只有一个标记实例:

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)

我将行名称添加到数据集中,将“标记”分隔为单独的行而不是单个列,删除了一些标记名称周围的额外引号,然后为每行创建1的虚拟列在扩展到宽幅之前。

如果每行可以有一个字符串的多个值:

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)