Как использовать функцию Spread, используя только одно значение целевого столбца? - PullRequest
3 голосов
/ 09 февраля 2020

У нас есть следующий фрейм данных a с чем-то вроде этого:


 > a
    google_prod      Value
1     categoria          ML
2        google         120
3       youtube          24
4     categoria          AO
5        google           2
6       youtube           0
7     categoria          ML
8        google          27
9       youtube           0
10    categoria          AO
11       google           5
12      youtube           0

Мы хотели бы получить это:

    categoria google_prod    Value
1          ML   google        120
2          ML   youtube        24
3          AO   google          2
4          AO   youtube         0      
5          ML   google         27
6          ML   youtube         0    
7          AO   google          5
8          AO    youtube        0    

Другими словами, выполните тип применение функции Spread или аналогичной функции, где для его применения берется только одно значение из столбца google_prod, в этом случае это будет значение категории.

Ответы [ 3 ]

2 голосов
/ 09 февраля 2020
library(tidyverse)

# getting the data
category <- rep(c("categoria",  "google",   "youtube"), 4)
value <- c("ML", "120", "24",   "AO",   "2",    "0",    "ML",   "27",   "0",    "AO",   "5",    "0")

df <- tibble(category, value)

df %>%
  mutate(helper = rep(1:(nrow(df)/3), each = 3)) %>%
  pivot_wider(names_from = category, values_from = value) %>%
  select(-helper) %>%
  pivot_longer(names_to = "google_prod",  values_to = "values", -1)

# # A tibble: 8 x 3
# categoria google_prod values
# <chr>     <chr>       <chr> 
# 1 ML        google      120   
# 2 ML        youtube     24    
# 3 AO        google      2     
# 4 AO        youtube     0     
# 5 ML        google      27    
# 6 ML        youtube     0     
# 7 AO        google      5 
# 8 AO        youtube     0 
1 голос
/ 09 февраля 2020

Вот еще одна идея с созданием группы с cumsum и извлечением элемента first

library(dplyr)
mydf %>% 
   group_by(grp = cumsum(google_prod == 'categoria')) %>% 
   mutate(categoria = first(Value)) %>% 
   slice(-1) %>% 
   ungroup %>%
   select(-grp) %>%
   type.convert(as.is = TRUE)
# A tibble: 8 x 3
#  google_prod Value categoria
#  <chr>       <int> <chr>    
#1 google        120 ML       
#2 youtube        24 ML       
#3 google          2 AO       
#4 youtube         0 AO       
#5 google         27 ML       
#6 youtube         0 ML       
#7 google          5 AO       
#8 youtube         0 AO       

data

mydf <- structure(list(google_prod = c("categoria", "google", "youtube", 
"categoria", "google", "youtube", "categoria", "google", "youtube", 
"categoria", "google", "youtube"), Value = c("ML", "120", "24", 
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")),
 class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
1 голос
/ 09 февраля 2020

Одна идея была бы следующей. Насколько я вижу шаблон, вы нацеливаетесь на значения, которые содержат две заглавные буквы в Value. Я искал, где они используют grep() и получил показатель. Используя эту информацию, я создал переменную группы, используя findIntervals(). Для каждой группы я агрегировал данные; Я извлек и поместил значение заглавной буквы в categoria. Аналогичным образом я создал еще две колонки. Это списки. Поэтому я использовал unnest() в конце, чтобы получить вывод.

library(tidyverse)

ind <- grep(x = mydf$Value, pattern = "[A-Z]+")

group_by(mydf, group = findInterval(x = 1:n(), vec = ind)) %>%
summarize(categoria = Value[google_prod == "categoria"],
          Google_prod = list(google_prod[google_prod != "categoria"]),
          Value = list(Value[google_prod != "categoria"])) %>% 
unnest(cols = Google_prod:Value)

  group categoria Google_prod Value
  <int> <chr>     <chr>       <chr>
1     1 ML        google      120  
2     1 ML        youtube     24   
3     2 AO        google      2    
4     2 AO        youtube     0    
5     3 ML        google      27   
6     3 ML        youtube     0    
7     4 AO        google      5    
8     4 AO        youtube     0    

DATA

mydf <- structure(list(google_prod = c("categoria", "google", "youtube", 
"categoria", "google", "youtube", "categoria", "google", "youtube", 
"categoria", "google", "youtube"), Value = c("ML", "120", "24", 
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
...