【问题标题】:How to use the Spread function using only one value of the target column?如何仅使用目标列的一个值来使用Spread函数?
【发布时间】:2020-02-09 15:07:08
【问题描述】:

我们有以下数据框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 列中获取一个值来应用它,在这种情况下,它将是 'categoria' 值。

【问题讨论】:

标签: r tidy spread


【解决方案1】:
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 

【讨论】:

    【解决方案2】:

    这是另一个想法,用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       
    

    数据

    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"))
    

    【讨论】:

      【解决方案3】:

      以下是一个想法。就我看到的模式而言,您的目标值在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    
      

      数据

      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"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-22
        • 1970-01-01
        • 2013-10-28
        • 2015-09-16
        • 1970-01-01
        • 2023-02-05
        • 2017-03-31
        • 2019-09-02
        相关资源
        最近更新 更多