【问题标题】:Rename columns in nested lists and row bind重命名嵌套列表和行绑定中的列
【发布时间】:2017-08-09 13:49:34
【问题描述】:

我有一个嵌套的对象列表,我想首先重命名一些变量并行绑定它的对象,但只选择一些变量。 在下面的示例中,我想将第二个对象中的列 A 重命名为 a,并将第三个对象中的 w 重命名为 x,然后行绑定所有三个对象,仅选择列 ax 使用。

数据:

df <- list(structure(list(a = 1:3, 
x = c(-1.99, -1.11, -0.34), 
y = c("C", "B", "A")), .Names = c("a", "x",                                                                                                  "y"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,                                                                                                                                                              -3L)), structure(list(a = 1:3, x = c(-0.44, -1.07,                                                                                                                                                                                                  -0.23)), .Names = c("A", "x"), class = c("tbl_df",                                                                                                                                                                                                                                           "tbl", "data.frame"), row.names = c(NA, -3L)), 
structure(list(a = 1:3, x = c(-0.62, -0.60, -0.06), 
y = c(3L, 2L, 1L)), .Names = c("a", "w", "y"), class = c("tbl_df",                                                                                                                                                                                                                                                                                                             "tbl", "data.frame"), row.names = c(NA, -3L)))

列表结构:

   > lapply(df, names)
[[1]]
[1] "a" "x" "y"

[[2]]
[1] "A" "x"

[[3]]
[1] "a" "w" "y"

然后,行绑定然后:

library(plyr)
df2 <- ldply(df, data.frame)

【问题讨论】:

    标签: r plyr


    【解决方案1】:

    使用purrr (map), dplyr(rename,select,bind_rows,%&gt;%) 和 magrittr (%&lt;&gt;%,%&gt;%):

    library(purrr)
    library(dplyr)
    library(magrittr)
    df[[2]] %<>% rename(.,a = A)
    df[[3]] %<>% rename(.,x = w)
    df %>% map_df(. %>% select("a","x"))
    # # A tibble: 9 x 2
    #       a     x
    #   <int> <dbl>
    # 1     1 -1.99
    # 2     2 -1.11
    # 3     3 -0.34
    # 4     1 -0.44
    # 5     2 -1.07
    # 6     3 -0.23
    # 7     1 -0.62
    # 8     2 -0.60
    # 9     3 -0.06
    

    或者在基础 R 中:

    names(df[[2]])[names(df[[2]]) == "A"] <- "a"
    names(df[[3]])[names(df[[3]]) == "w"] <- "x"
    do.call(rbind,lapply(df,"[",c("a","x")))
    

    【讨论】:

    • 也许提到 %&lt;&gt;% 来自 magrittr,而不是 tidyrdplyr
    • 其实那里没有tidyr,但是map来自purrr
    • 另外,您可以使用map_df(内部使用bind_rows())代替map() ... bind_rows()
    • 漂亮,我不知道这个,我编辑使用它
    【解决方案2】:

    您可以通过以下方式实现:

    library(plyr)
    df = lapply(df, function(x) {plyr::rename(x,c("A"="a","w"="x"),warn_missing = F)})
    df2 <- ldply(lapply(df, function(x) {x[,c("a","x")]}), data.frame)
    

    输出:

      a     x
    1 1 -1.99
    2 2 -1.11
    3 3 -0.34
    4 1 -0.44
    5 2 -1.07
    6 3 -0.23
    7 1 -0.62
    8 2 -0.60
    9 3 -0.06
    

    希望这会有所帮助。

    【讨论】:

    • 您认为我必须将对象位置精确定位为colnames(df[[2]])[1]="a" 还是我可以使用列的名称来代替?这很重要,因为我的真实数据对象有超过 500 个列表,假设我必须重命名其中的大约 100 个……如果存在更有效的方法,那就太好了。无论如何,谢谢。
    • 嗨 Marie-Eve,请查看我的答案的补充内容,它应该涵盖该场景。
    【解决方案3】:

    另一个想法可能是使用替换值创建一个命名向量 v,循环遍历您的列表,如果匹配则重命名并选择所需的列。

    v <- c("a" = "A", "x" = "w")
    
    map_df(df, .f = ~ rename_if(
      .x, 
      .p = names(.x) %in% v, 
      .f = funs(stringi::stri_replace_all_fixed(., v, names(v), vectorize_all = FALSE))) %>% 
        select(names(v))
    )
    

    这给出了:

    ## A tibble: 9 x 2
    #      a     x
    #  <int> <dbl>
    #1     1 -1.99
    #2     2 -1.11
    #3     3 -0.34
    #4     1 -0.44
    #5     2 -1.07
    #6     3 -0.23
    #7     1 -0.62
    #8     2 -0.60
    #9     3 -0.06
    

    【讨论】:

      猜你喜欢
      • 2019-08-07
      • 2022-11-17
      • 2016-06-04
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      相关资源
      最近更新 更多