【问题标题】:pivot_longer two sets of variables into two columnspivot_longer 将两组变量分成两列
【发布时间】:2021-07-21 14:51:39
【问题描述】:

我想根据两组变量将 pivot_longer 分成两列。

例如:

df <- data.frame(year = rep(c(2010,2012,2017), 4),
                 party = rep(c("A", "A", "A", "B", "B", "B"), 2),
                 pp1 = rep(c(3,4,5,1,2,6), 2), 
                 pp2 = rep(c(1,2,3,4,5,6), 2),
                 pp3 = rep(c(6,2,3,1,5,4), 2),
                 l_pp1 = rep(c(1,2,6,3,4,5), 2), 
                 l_pp2 = rep(c(4,5,6,1,2,3), 2),
                 l_pp3 = rep(c(1,5,4,6,2,3), 2))

数据:

   year party pp1 pp2 pp3 l_pp1 l_pp2 l_pp3
1  2010     A   3   1   6     1     4     1
2  2012     A   4   2   2     2     5     5
3  2017     A   5   3   3     6     6     4
4  2010     B   1   4   1     3     1     6
5  2012     B   2   5   5     4     2     2
6  2017     B   6   6   4     5     3     3
7  2010     A   3   1   6     1     4     1
8  2012     A   4   2   2     2     5     5
9  2017     A   5   3   3     6     6     4
10 2010     B   1   4   1     3     1     6
11 2012     B   2   5   5     4     2     2
12 2017     B   6   6   4     5     3     3

我需要的是以下内容:

   year party  area pp l_pp
1  2010     A   1   3   1
2  2012     A   1   4   2
3  2017     A   1   5   6
4  2010     B   1   1   3
5  2012     B   1   2   4
etc.

这里 pp 和 l_pp 是同一个区域(pp1 & l_pp1 成为区域 1 的 pp 和 l_pp)。

我会这样想,但 values_to 只能取 1 的大小。

df <- df %>%
  pivot_longer(!c("party", "year"), names_to = "area", values_to = c("pp", "l_pp"))

这让我很接近,但不是我想要的:

df <- df %>%
  pivot_longer(!c("party", "year"), names_to = "area", values_to = c("pp"))
   year party  area pp
1  2010     A   pp1  3
2  2010     A   pp2  1
3  2010     A   pp3  6
4  2010     A l_pp1  1
5  2010     A l_pp2  4
6  2010     A l_pp3  1

【问题讨论】:

    标签: r dplyr pivot


    【解决方案1】:

    编辑利用 .value 哨兵,这可以通过一个 pivot_longer 来实现,如下所示:

    library(tidyr)
    
    df %>% 
      pivot_longer(-c(year, party), names_to = c(".value", "area"), names_pattern = "^(.*?)(\\d+)$")
    #> # A tibble: 36 × 5
    #>     year party area     pp  l_pp
    #>    <dbl> <chr> <chr> <dbl> <dbl>
    #>  1  2010 A     1         3     1
    #>  2  2010 A     2         1     4
    #>  3  2010 A     3         6     1
    #>  4  2012 A     1         4     2
    #>  5  2012 A     2         2     5
    #>  6  2012 A     3         2     5
    #>  7  2017 A     1         5     6
    #>  8  2017 A     2         3     6
    #>  9  2017 A     3         3     4
    #> 10  2010 B     1         1     3
    #> # … with 26 more rows
    

    作为第二种选择,可以通过额外的pivot_wider 来实现相同的结果,就像这样,作为中间步骤,必须添加一个 id 列来唯一标识数据中的行:

    library(dplyr)
    library(tidyr)
    
    df %>% 
      pivot_longer(!c(year, party), names_to = c("var", "area"), names_pattern = "(.*)(\\d)") %>% 
      group_by(year, party, area, var) %>% 
      mutate(id = row_number()) %>% 
      ungroup() %>% 
      pivot_wider(names_from = var, values_from = value)
    #> # A tibble: 36 x 6
    #>     year party area     id    pp  l_pp
    #>    <dbl> <chr> <chr> <int> <dbl> <dbl>
    #>  1  2010 A     1         1     3     1
    #>  2  2010 A     2         1     1     4
    #>  3  2010 A     3         1     6     1
    #>  4  2012 A     1         1     4     2
    #>  5  2012 A     2         1     2     5
    #>  6  2012 A     3         1     2     5
    #>  7  2017 A     1         1     5     6
    #>  8  2017 A     2         1     3     6
    #>  9  2017 A     3         1     3     4
    #> 10  2010 B     1         1     1     3
    #> # … with 26 more rows
    

    【讨论】:

      猜你喜欢
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 2016-09-15
      • 2020-08-05
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多