Подсчет появления элементов в строке - PullRequest
1 голос
/ 16 июня 2019

У меня есть следующий набор данных:

structure(list(ID = c(5L, 6L, 7L, 8L, 10L), chain = c("x49", 
                                                      "x43", "x32 > x42 > x49 > x45 > x20 > x50 > x38", "x54 > x44", 
                                                      "x38 > x38")), row.names = c(NA, -5L), class = c("data.table", 
                                                                                                       "data.frame"))

   ID                                   chain
1:  5                                     x49
2:  6                                     x43
3:  7 x32 > x42 > x49 > x45 > x20 > x50 > x38
4:  8                               x54 > x44
5: 10                               x38 > x38

В столбцах цепочки представлен процесс покупки продукта, а также отсутствует некоторая информация ( начало и покупка ). Цель состоит в том, чтобы дважды подсчитать каждое значение в цепочке ( origin например из и destination например, до ). Мне нужно реструктурировать набор данных. Например, реструктурированная цепочка x54 > x44 должна выглядеть так:

   from  to
1 start x54
2   x54 x44
3   x44 buy

Весь результат должен выглядеть так:

    from  to
1  start x49
2    x49 buy
3  start x43
4    x43 buy
5  start x32
6    x32 x42
7    x42 x49
8    x49 x45
9    x45 x20
10   x20 x50
11   x38 buy
12 start x54
13   x54 x44
14   x44 buy
15 start x54
16   x54 x44
17   x44 buy
18 start x38
19   x38 x38
20   x38 buy

Я уже пробовал это, но я не уверен, что это хорошая идея (также не знаю, как это сделать).

df <- strsplit(df$chain, ">")
lapply(df, trimws)

Производительность может быть важной, поскольку цепочки могут стать довольно длинными (30 элементов), а весь набор данных содержит 100 тыс. Строк.

Ответы [ 2 ]

1 голос
/ 16 июня 2019

Мы можем вставить строки в начале и конце с помощью str_c, используйте separate_rows, чтобы расширить набор данных с помощью tidyverse

library(tidyverse)
dt %>%
   mutate(chain = str_c("start > ", chain, " > buy")) %>%
   separate_rows(chain) %>% group_by(ID) %>% 
   transmute(from = chain, to = lead(chain)) %>% 
   na.omit %>% 
   ungroup %>% 
   select(-ID)
# A tibble: 18 x 2
#   from  to   
#   <chr> <chr>
# 1 start x49  
# 2 x49   buy  
# 3 start x43  
# 4 x43   buy  
# 5 start x32  
# 6 x32   x42  
# 7 x42   x49  
# 8 x49   x45  
# 9 x45   x20  
#10 x20   x50  
#11 x50   x38  
#12 x38   buy  
#13 start x54  
#14 x54   x44  
#15 x44   buy  
#16 start x38  
#17 x38   x38  
#18 x38   buy  
1 голос
/ 16 июня 2019

Основной способ R состоит в том, чтобы разбить строки на " > " и создать кадр данных, объединяющий все значения.

do.call(rbind, lapply(strsplit(df$chain, " > "), function(x) 
               data.frame(from = c("start",x), to = c(x, "buy"))))

#    from  to
#1  start x49
#2    x49 buy
#3  start x43
#4    x43 buy
#5  start x32
#6    x32 x42
#7    x42 x49
#8    x49 x45
#9    x45 x20
#10   x20 x50
#11   x50 x38
#12   x38 buy
#13 start x54
#14   x54 x44
#15   x44 buy
#16 start x38
#17   x38 x38
#18   x38 buy

При использовании аналогичного подхода tidyverse будет

library(tidyverse)
map_dfr(str_split(df$chain, " > "), ~tibble(from = c("start",.), to = c(., "buy")))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...