Разделить столбец данных с разделенным запятыми списком тегов - PullRequest
0 голосов
/ 12 февраля 2020

Я имею дело с набором данных продуктов, которые характеризуются тегами. То есть у них есть свойство, которое состоит из списка слов, разделенных запятыми. Например,

data.frame(
   id = c(11, 12, 13),
   tags =c("wood,small,old","big,iron,artistic", "pretty,wood")
)

Я хотел бы разделить столбец тегов на разные логические столбцы для каждого тега, а именно

| id | wood | iron | small |  big |  old | artistic | pretty | 
------------------------------------------------------------
| 11 |  TRUE| FALSE|   TRUE| FALSE|  TRUE|     FALSE|   FALSE|
| 12 | FALSE|  TRUE|  FALSE|  TRUE| FALSE|      TRUE|   FALSE|
| 13 |  TRUE| FALSE|  FALSE| FALSE| FALSE|     FALSE|    TRUE|

Я пытался использовать функцию separate из tidyr, но теги неупорядочены, и тогда трудно создать столбец для каждого тега.

Я нашел решение, используя пакет mutate из dplyr и создав вручную столбец для каждый тег

has_tag <- function(tag, tags) {
    strsplit(tags, ",") %>% map_lgl(function(x) tag %in% x)
}

df %>% 
    mutate(
        wood = has_tag("wood", tags),
        iron = has_tag("iron", tags),
        ...
    )

, но в будущем могут появиться новые теги, и я хотел бы сделать его масштабируемым.

¿Есть ли способ сделать это легко?

Ответы [ 2 ]

3 голосов
/ 12 февраля 2020

Вы можете сделать:

library(tidyverse)
df %>% 
   separate_rows(tags) %>%
    mutate(val = TRUE) %>%
    spread(tags, val, FALSE)
      id artistic   big  iron   old pretty small  wood
    1 11    FALSE FALSE FALSE  TRUE  FALSE  TRUE  TRUE
    2 12     TRUE  TRUE  TRUE FALSE  FALSE FALSE FALSE
    3 13    FALSE FALSE FALSE FALSE   TRUE FALSE  TRUE

с основанием R требуется немного шагов:

as.data.frame.matrix(xtabs(f~ind+values,
      cbind(stack(setNames(strsplit(as.character(df$tags),","),df$id)),f = 1))>0)

   artistic   big  iron   old pretty small  wood
11    FALSE FALSE FALSE  TRUE  FALSE  TRUE  TRUE
12     TRUE  TRUE  TRUE FALSE  FALSE FALSE FALSE
13    FALSE FALSE FALSE FALSE   TRUE FALSE  TRUE
0 голосов
/ 12 февраля 2020

Мы можем использовать cSplit_e из splitstackshape для создания двоичного столбца, затем rename столбцы, удалив префикс

library(splitstackshape)
library(dplyr)
library(stringr)
cSplit_e(df1, 'tags', sep=",", type = 'character', fill = 0, drop = TRUE) %>%
    mutate_at(-1, as.logical) %>%
    rename_at(-1, ~ str_remove(., 'tags_'))
#  id artistic   big  iron   old pretty small  wood
#1 11    FALSE FALSE FALSE  TRUE  FALSE  TRUE  TRUE
#2 12     TRUE  TRUE  TRUE FALSE  FALSE FALSE FALSE
#3 13    FALSE FALSE FALSE FALSE   TRUE FALSE  TRUE

Или более компактно

library(qdapTools)
cbind(df1[1],  mtabulate(strsplit(as.character(df1$tags), ",")))
...