R - Yelp data Столбец бизнес-категории имеет несколько категорий на бизнесХотите разделить на категории конкретные столбцы со значениями 1 и 0 - PullRequest
1 голос
/ 28 марта 2019

Заранее благодарю всех, кто собирается попытаться помочь с этим.

Я использую набор данных Yelp, и на вопрос, на который я хочу ответить, «какие категории положительно коррелируют с высшими звездами»для категории X (столбцы, например) "

Проблема, с которой я сталкиваюсь, заключается в том, что для каждого бизнеса категории объединяются в один столбец и строку для businesss_id.Поэтому мне нужны средства, чтобы отделить каждую категорию, превратить их в столбцы, а затем проверить, содержит ли исходный столбец категории категорию, для которой был создан столбец.

В настоящее время я думаю использовать group_by с business_idи затем unnest_tokens столбец, затем model.matrix () этот столбец в нужное мне разделение и затем присоедините его к df, который я использую.Но я не могу заставить model.matrix передавать и сохранять business_id подключенным к каждой строке.

# an example of what I am using #
df <- 
  data_frame(business_id = c("bus_1",
                             "bus_2", 
                             "bus_3"),
             categories=c("Pizza, Burgers, Caterers",
                          "Pizza, Restaurants, Bars",
                          "American, Barbeque, Restaurants"))

# what I want it to look like #
desired_df <- 
  data_frame(business_id = c("bus_1",
                             "bus_2",
                             "bus_3"),
             categories=c("Pizza, Burgers, Caterers",
                          "Pizza, Restaurants, Bars",
                          "American, Barbeque, Restaurants"),
             Pizza = c(1, 1, 0),
             Burgers = c(1, 0, 0),
             Caterers = c(1, 0, 0),
             Restaurants = c(0, 1, 1),
             Bars = c(0, 1, 0),
             American = c(0, 0, 1),
             Barbeque = c(0, 0, 1))

# where I am stuck #
df %>%
  select(business_id, categories) %>% 
  group_by(business_id) %>% 
  unnest_tokens(categories, categories, token = 'regex', pattern=", ") %>%
  model.matrix(business_id ~ categories, data = .) %>% 
  as_data_frame

Редактировать: После этого поста и ответов ниже я столкнулся с ошибкой дублирующихся идентификаторов с использованием spread ().Это привело меня к этой теме https://github.com/tidyverse/tidyr/issues/426, где был опубликован ответ на мой вопрос. Я опубликовал его ниже.

#, дублируя ошибку с меньшим data.frame #

library(tidyverse)
 df <- structure(list(age = c("21", "17", "32", "29", "15"), 
                        gender = structure(c(2L, 1L, 1L, 2L, 2L), .Label = c("Female", "Male"), class = "factor")), 
                   row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"), .Names = c("age", "gender"))
 df
#> # A tibble: 5 x 2
#>   age   gender
#>   <chr> <fct> 
#> 1 21    Male  
#> 2 17    Female
#> 3 32    Female
#> 4 29    Male  
#> 5 15    Male  

df %>% 
  spread(key=gender, value=age)
#> Error: Duplicate identifiers for rows (2, 3), (1, 4, 5)

# устранение проблемы #

df %>% 
  group_by_at(vars(-age)) %>%  # group by everything other than the value column. 
  mutate(row_id=1:n()) %>% ungroup() %>%  # build group index
  spread(key=gender, value=age) %>%    # spread
  select(-row_id)  # drop the index

#> # A tibble: 3 x 2
#>   Female Male 
#>   <chr>  <chr>
#> 1 17     21   
#> 2 32     29   
#> 3 NA     15   

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Построение из вашего приятного использования tidytext::unnest_tokens(), вы также можете использовать это альтернативное решение

library(dplyr)
library(tidyr)
library(tidytext)

df %>%
  select(business_id, categories) %>% 
  group_by(business_id) %>% 
  unnest_tokens(categories, categories, token = 'regex', pattern=", ") %>% 
  mutate(value = 1) %>% 
  spread(categories, value, fill = 0)
# business_id american barbeque  bars burgers caterers pizza restaurants
# <chr>          <dbl>    <dbl> <dbl>   <dbl>    <dbl> <dbl>       <dbl>
# bus_1              0        0     0       1        1     1           0
# bus_2              0        0     1       0        0     1           1
# bus_3              1        1     0       0        0     0           1
0 голосов
/ 28 марта 2019

Вот простое решение:

library(tidyverse)

df %>% 
  mutate(
    ind = 1,
    tmp = strsplit(categories, ", ")
  ) %>% 
  unnest(tmp) %>% 
  spread(tmp, ind, fill = 0)
## A tibble: 3 x 9
#  business_id categories                      American Barbeque  Bars Burgers Caterers Pizza Restaurants
#  <chr>       <chr>                              <dbl>    <dbl> <dbl>   <dbl>    <dbl> <dbl>       <dbl>
#1 bus_1       Pizza, Burgers, Caterers               0        0     0       1        1     1           0
#2 bus_2       Pizza, Restaurants, Bars               0        0     1       0        0     1           1
#3 bus_3       American, Barbeque, Restaurants        1        1     0       0        0     0           1
...