Как преобразовать строку в переменную и в l oop через group_by? - PullRequest
0 голосов
/ 17 января 2020

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

data%>% 
  group_by(Location,Product)%>%
  summarize(n=n()) %>%
  pivot_wider(names_from = product, values_from = n) 

Теперь представьте, что вместо одного столбца Продукт у меня есть US_Product, Japan_Product, ..., Germany_Product. Как я могу создать свои таблицы на случай непредвиденных обстоятельств в течение l oop? ПРИМЕЧАНИЕ: когда я создаю вектор продуктов, таких как p<-c("Product1", "Product2",..., "Product3") и l oop, через эти продукты, я получаю сообщение об ошибке, потому что это строки, а не имена переменных.

Вот минимальный пример:

Location <- c("AB","ON","MN","AB","ON")
Product1<-c("Type1","Type2","Type1","Type3","Type1")
Product2<-c("Type3","Type2","Type3","Type3","Type2")
Product3<-c("Type1","Type2","Type1","Type1","Type1")
data <- tibble(Location,Product1,Product2,Product3)
data%>% 
  group_by(Location,Product1)%>%
  summarize(n=n()) %>%
  pivot_wider(names_from = Product1, values_from = n) #this works as expected

#now I want to do the same thing in a loop
prodV <- c("Product1","Product2","Product3")
for (i in c(1:3)){
  var <- prodV[i]
  data%>% 
    group_by(Location,var)%>%
    summarize(n=n()) %>%
    pivot_wider(names_from = var, values_from = n)   
}

Ответы [ 3 ]

0 голосов
/ 17 января 2020

Не уверен, что вам нужно следующее. Ниже приведено базовое решение R для создания таблиц на случай непредвиденных обстоятельств:

p <- c("US_Product","Japan_product","Germany_Product")
res <- Map(function(x) table(df[c("Location",x)]),p)

, таких, что

> res
$US_Product
        US_Product
Location a b c
      XX 2 0 1
      YY 1 1 2

$Japan_product
        Japan_product
Location d e f
      XX 0 2 1
      YY 3 0 1

$Germany_Product
        Germany_Product
Location g i j
      XX 0 3 0
      YY 1 1 2

Dummy DATA

df <- > dput(df)
structure(list(Location = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
2L), .Label = c("XX", "YY"), class = "factor"), US_Product = structure(c(1L, 
3L, 1L, 2L, 1L, 3L, 3L), .Label = c("a", "b", "c"), class = "factor"), 
    Japan_product = structure(c(2L, 2L, 3L, 3L, 1L, 1L, 1L), .Label = c("d", 
    "e", "f"), class = "factor"), Germany_Product = structure(c(2L, 
    2L, 2L, 2L, 3L, 1L, 3L), .Label = c("g", "i", "j"), class = "factor")), class = "data.frame", row.names = c(NA, 
-7L))
0 голосов
/ 18 января 2020

Я смог решить проблему, используя group_by_at вместо group_by. Согласно dplyr: в чем разница между функциями group_by и group_by_? , если нужно иметь вводы с кавычками, следует использовать SE-версии функций вместо NSE-версий - см. Ссылку для подробное объяснение.

prodV <- c("Product1","Product2","Product3")
for (i in c(1:3)){
  var <- prodV[i]
  a<-data%>% 
    group_by_at(vars("Location",var))%>%
    summarize(n=n()) %>%
    pivot_wider(names_from = var, values_from = n)   
  print(a)
}
0 голосов
/ 17 января 2020

Если нам нужно использовать его в al oop, тогда один из вариантов будет map

library(dplyr)
library(purrr)
library(tidyr)
map(p, ~ 
         data%>% 
           group_by_at(vars("Location", .x)) %>%
           summarize(n=n()) %>%
           pivot_wider(names_from = .x, values_from = n))

Используя воспроизводимый пример

data(mtcars)
p <- c("cyl", "vs", "am")
map(p, ~ 
         mtcars %>% 
             group_by_at(vars('gear', .x)) %>% 
             summarise(n = n()) %>%
             pivot_wider(names_from = .x, values_from = n) ) 

Или, если мы используем for l oop, то создаем пустой list для хранения результатов каждой итерации ('out'), l oop над значениями 'p' и изменяем только .x часть из map при назначении вывода каждому элементу 'out' list

out <- vector('list', length(p))
names(out) <- p
for(p1 in p) {
       out[[p1]] <- data %>%
                      group_by_at(vars("Location", p1)) %>%
                      summarize(n = n()) %>%
                      pivot_wider(names_from = p1, values_from = n)
   }
...