将变量传递到tidyr :: pivot_wider

时间:2020-09-29 01:14:25

标签: r tidyr tidyeval r-glue

以下是一些愚蠢的数据,我们使用两个名称进行了更广泛的介绍:

library(tidyr)

df <- data.frame(
    food = c('banana','banana','banana','banana','cheese','cheese','cheese','cheese'),
    binary = c(rep(c('yes','no'), 4)),
    car = c('toyota','subaru','mazda','skoda','toyota','subaru','mazda','skoda'),
    fun = c(2,4,3,6,2,4,2,3))

df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(car, binary),
        values_from = fun)

如果我们想将新变量名的格式(例如,从toyota_yes更改为yes_toyota,请使用names_glue参数:

df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(car, binary),
        names_glue = "{binary}_{car}",
        values_from = fun)

我面临的问题是找到正确的语法来将变量名传递给names_glue参数。将变量传递到names_from很容易,例如:

var1 <- 'car'
var2 <- 'binary'
df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(var1, var2),
        values_from = fun)

但是我们不能直接使用names_glue来做到这一点:

df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(var1, var2),
        names_glue = "{var1}_{var2}",
        values_from = fun)

错误:列名car_binarycar_binarycar_binary不能重复。

大概是在评估变量,只是将结果字符串(即“ car”或“ binary”)传递到粘胶函数中。我玩了一些通常用于整洁评估的东西(!!sym(...)等),但没有任何工作。期望的输出如下,使用变量names_glue

# A tibble: 2 x 5
  food   yes_toyota no_subaru yes_mazda no_skoda
  <fct>       <dbl>     <dbl>     <dbl>    <dbl>
1 banana          2         4         3        6
2 cheese          2         4         2        3

Here is the commit that added the names_glue parameter to pivot_wider -- although I can't really figure out how to troubleshoot with this.

2 个答案:

答案 0 :(得分:3)

您可以使用sprtinf / paste0来构造字符串:

library(tidyr)
df %>%
  pivot_wider(
    id_cols = food,
    names_from = c(var1, var2),
    names_glue = sprintf('{%s}_{%s}', var2, var1),
    values_from = fun)

#  food   yes_toyota no_subaru yes_mazda no_skoda
#  <chr>       <dbl>     <dbl>     <dbl>    <dbl>
#1 banana          2         4         3        6
#2 cheese          2         4         2        3

答案 1 :(得分:1)

我们可以使用glue

创建模式
library(dplyr)
library(tidyr)
df %>%
     pivot_wider(
         id_cols = food,
         names_from = c(var1, var2),
         names_glue = glue::glue("{[var1]}_{[var2]}", .open = '[', .close = ']'),
         values_from = fun)
# A tibble: 2 x 5
#  food   toyota_yes subaru_no mazda_yes skoda_no
#  <chr>       <dbl>     <dbl>     <dbl>    <dbl>
#1 banana          2         4         3        6
#2 cheese          2         4         2        3