按行值重命名分组的 tibble 中的列 (dplyr)

Rename column in grouped tibble by row value (dplyr)

如何根据特定的行值重命名分组的 dplyr tibble 中的列?下图显示了我的 tibble 处理前的样子以及处理后的样子。

我试过下面的代码,但没能写出能够从"name"列灵活声明新列名的列重命名函数。

library(dplyr)

df <- data.frame(
 "splitvar"=c(1,1,1,2,2,3,3,3,3),
 "value"=c(1,4,2,5,6,9,11,13,12),
 "name"=c("Harold","Harold","Harold","Jane","Jane","George","George","George","George"),
 stringsAsFactors=F
)

grouped_tbl <- df %>%
  group_by( splitvar ) %>%
  eval(parse(
    paste0("rename(",unique(name)," = value)")
  ))

相关:Replacement for "rename" in dplyr

像这样:

library(tidyverse)

df %>% 
  split(.$splitvar) %>% 
  map(~rename(., !!unique(.$name) := "value"))

我花了一些时间来理解这个问题,但试着看看 programming with dplyr

代码的输出是:

$`1`
  splitvar Harold   name
1        1      1 Harold
2        1      4 Harold
3        1      2 Harold

$`2`
  splitvar Jane name
4        2    5 Jane
5        2    6 Jane

$`3`
  splitvar George   name
6        3      9 George
7        3     11 George
8        3     13 George
9        3     12 George

您可以分开,创建新的列,然后重新绑定在一起。

这是通过 nest/unnest (tidyr) 和 map (purrr)

library(tidyr)
library(purrr)

我使用 rename_at 作为 tidyeval 的替代品。

df %>%
    group_by(splitvar) %>%
    nest() %>%
    mutate(data = map(data, function(x) rename_at(x, "value", funs( unique(x$name) ) ) ) ) %>%
    unnest()

# A tibble: 9 x 5
  splitvar Harold   name  Jane George
     <dbl>  <dbl>  <chr> <dbl>  <dbl>
1        1      1 Harold    NA     NA
2        1      4 Harold    NA     NA
3        1      2 Harold    NA     NA
4        2     NA   Jane     5     NA
5        2     NA   Jane     6     NA
6        3     NA George    NA      9
7        3     NA George    NA     11
8        3     NA George    NA     13
9        3     NA George    NA     12

这可能是一个 "reshaping" 问题,我通过 tidyr 解决了这个问题。不过,这不会保留 name 列。

df %>%
    group_by(splitvar) %>%
    mutate(row = row_number() ) %>%
    spread(name, value)

# A tibble: 9 x 5
# Groups:   splitvar [3]
  splitvar   row George Harold  Jane
*    <dbl> <int>  <dbl>  <dbl> <dbl>
1        1     1     NA      1    NA
2        1     2     NA      4    NA
3        1     3     NA      2    NA
4        2     1     NA     NA     5
5        2     2     NA     NA     6
6        3     1      9     NA    NA
7        3     2     11     NA    NA
8        3     3     13     NA    NA
9        3     4     12     NA    NA