【问题标题】:How can I use map2 and rename_with to modify nested column names?如何使用 map2 和 rename_with 修改嵌套列名?
【发布时间】:2021-04-18 21:40:21
【问题描述】:

我正在尝试根据未嵌套列的值重命名嵌套数据框中的一组列。这是数据集的简化示例:

library(tidyverse)

df_pre <- tribble(
  ~year, ~data,
  1970, tibble(GEOID_1970 = 1, TOTPOP_1970 = 2),
  1980, tibble(GEOID_1980 = 3, TOTPOP_1980 = 4)
)  

使用purrr,我想重命名嵌套列,以便拥有以下内容:

df_post <- tribble(
  ~year, ~data,
  1970, tibble(GEOID = 1, TOTPOP = 2),
  1980, tibble(GEOID = 3, TOTPOP = 4)
)  

我尝试了多种方法,所有这些方法都会引发某种错误,例如:

library(purrr)
df_post <- df_pre %>% map2(.x = data, .y = year, 
                           ~ rename_with(str_replace,  
                                        pattern = paste0("_", .y), 
                                        replacement = ""))
#> Error: Can't convert a `tbl_df/tbl/data.frame` object to function

如何使用map2 加上rename_with 来修改嵌套列名?除了解决这个特殊问题之外,我还试图更深入地了解如何将诸如年份之类的参数传递给 map2 匿名函数。

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    我们使用map 循环遍历list 列“数据”并使用rename_with 选择所有列(everything()),同时使用str_remove 从列名称中删除后缀部分)

    library(dplyr)
    library(purrr)
    library(stringr)
    df_new <- df_pre  %>%
        mutate(data = map(data, ~ .x %>%
              rename_with(~ str_remove(., "_\\d+$"), everything())))
    

    -检查

    identical(df_new, df_post)
    #[1] TRUE
    

    如果我们想使用带有map2的“年份”列

    df_new <- df_pre %>%
          mutate(data = map2(data, year, ~  {
                  yr <- .y
                  .x %>% rename_with(~ str_remove(., str_c("_", yr)), everything())
                  }))
    

    -检查

    identical(df_new, df_post)
    #[1] TRUE
    

    【讨论】:

    • 非常感谢。我试图理解需要在匿名函数中分配 .y 的一般原则。您能否提供任何其他见解?
    • @nicholas 在您的代码中,列被拉到mutate/summarise 之外,因此您可能需要df_pre %&gt;% {map2(.x = .$data, .y = .$year, ~ .x)}
    • 此代码 (df_pre %&gt;% {map2(.x = .$data, .y = .$year, ~ .x)}) 创建了一个包含两个小标题的列表。我不明白它如何解决我关于作业的问题。任何见解将不胜感激。
    • @nicholas 我只是想说明您的代码在开始时不正确的地方,因为它不适用于 map2(data, year) 因为这些对象是 data.frame 中的列跨度>
    • @akrun 您的解决方案对我有用。您是否介意更详细地解释两个元素:1)为什么在 mutate() 的调用中需要花括号 {},以及 2)为什么需要这个赋值 yr &lt;= .y
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2019-03-04
    • 1970-01-01
    • 2019-10-18
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多