【问题标题】:Fill a dataframe by matching the values of a vector with colnames通过将向量的值与 colnames 匹配来填充数据框
【发布时间】:2020-11-19 14:27:32
【问题描述】:

我需要通过将向量的值与列名匹配来填充 R 中的数据框。 列名与向量的名称不完全匹配。 下面是一个例子:

df = data.frame(matrix(NA, ncol = 3, nrow = 4));
colnames(df) = c("AA", "BB", "CC")
vec1 = c(1,2,3) ; names(vec1) = c("BB745","456AA",  "123CC3") ;
vec2 = c(4,5,6) ; names(vec2) = c("BB745","456AA",  "123CC3") 

df 的第一行应该是

2 1 3
5 4 6

实现这一目标的最简单方法是什么?

提前致谢!

【问题讨论】:

    标签: r dataframe vector


    【解决方案1】:

    根据您的示例,我想您有许多 vecs,您希望将它们全部设置在一个基于数据框的部分公共部分的名称中。

    例如,你有这三个vecs:

    vec1 <- setNames(c(1,2,3), c("BB745","456AA",  "123CC3"))
    vec2 <- setNames(c(3,2,1), c("BB345","113AA",  "543CC6"))
    vec3 <- setNames(c(2,1,3), c("BB567","AA111",  "345CC8"))
    

    并且您想根据以下字符串的存在将它们设置在一起:

    nn <-  c("AA", "BB", "CC")
    

    在这种情况下,我建议您按照以下方式进行。

    在一个列表中设置您的vec

    l <- list(vec1,vec2,vec3)
    

    然后使用这一行:

    library(purrr)
    library(stringr)
    
    nn_clps <- paste(nn, collapse = "|")
    map_dfr(l, ~setNames(., str_extract(names(.), nn_clps))) %>% select(all_of(nn))
    
    #> # A tibble: 3 x 3
    #>      AA    BB    CC
    #>   <dbl> <dbl> <dbl>
    #> 1     2     1     3
    #> 2     2     3     1
    #> 3     1     2     3
    

    它有什么作用?

    • 我们使用来自purrr 包的map 对每个向量应用一个函数
    • 这样,我们每次取一个vec,并从名称中提取nn中的字符串:所以AABBCC之一。为此,我们使用 stringr 包中的 str_extract
    • 然后我们用我们提取的字符串重命名每个向量。我们使用setNames
    • 最后,所有字符串都设置在一个唯一的数据帧中。这是由map_dfr 执行的,其行为类似于map,但将输出定义为一个唯一的数据帧(dfr 代表将行绑定到数据帧)。
    • 要按预期顺序设置列,有多种方法。一种可能是来自dplyr 包中的selectall_of 只是翻译从 select 可以理解的名称中的字符串。同样[nn] 而不是 %&gt;% select(all_of(nn)) 也可以正常工作。像这样:
    map_dfr(l, ~setNames(., str_extract(names(.), nn_clps)))[nn]
    

    查看?map 以了解.~ 的作用。 简而言之:创建匿名函数需要~.是匿名函数中x的占位符。


    所有代码放在一起。 我稍微修改了它以按照您想要的顺序设置列。

    vec1 <- setNames(c(1,2,3), c("BB745","456AA","123CC3"))
    vec2 <- setNames(c(3,2,1), c("BB345","113AA","543CC6"))
    vec3 <- setNames(c(2,1,3), c("BB567","AA111","345CC8"))
    nn <- c("AA", "BB", "CC")
    l <- list(vec1,vec2,vec3)
    library(purrr)
    library(stringr)
    library(dplyr)
    nn_clps <- paste(nn, collapse = "|")
    map_dfr(l, ~setNames(., str_extract(names(.), nn_clps))) %>% select(all_of(nn))
    

    【讨论】:

    • 非常感谢您的回答。你已经明白我的问题了!当我运行您的代码时,Argument 1 must have namesmap_dfr 函数出现错误。
    • 您能否将我答案的最后一部分“所有代码放在一起”并运行它?告诉我你是否还有这个错误。因为我没有。
    • 是的,我仍然有错误。我在 2 个不同的 R 上尝试了您的代码。也许您的代码使用了存储在您的环境中的变量?
    • 你能更新你的包吗?请更新purrrdplyrtibble
    • 是的。看看最后的代码。我稍微修改了一下。
    【解决方案2】:

    使用tidyverse 函数尝试这种方法。您可以调整数据框中的向量,然后使用left_join() 清理值以进行匹配。代码如下:

    library(tidyverse)
    #Code
    newdf <- df %>% mutate(Ref=row_number()) %>%
      pivot_longer(-Ref) %>%
      left_join(
        vec1 %>% data.frame() %>% set_names(.,'Val') %>% rownames_to_column('name') %>%
          mutate(name=gsub("[[:digit:]]", "", name))
      ) %>%
      mutate(value=Val) %>% select(-Val) %>%
      pivot_wider(names_from = name,values_from=value) %>%
      select(-Ref)
    

    输出:

    # A tibble: 4 x 3
         AA    BB    CC
      <dbl> <dbl> <dbl>
    1     2     1     3
    2     2     1     3
    3     2     1     3
    4     2     1     3
    

    【讨论】:

      【解决方案3】:

      如果你只想要一个基本的 R 方法,这样的方法可以工作:

      vec1 <- c(1,2,3) ; names(vec1) <- c("BB745","456AA", "123CC3") 
      vec2 <- c(3,4,5) ; names(vec2) <- c("BB845","545AA", "456CC3") 
      
      my_fun <- function(vec) {
        headers <- c("AA", "BB", "CC")
        new_vals <- sapply(headers, 
                      function(x) {
                        idx <- grepl(x, names(vec))
                        vec[idx]
                      })
        names(new_vals) <- headers
        new_vals
      }
      row_list <- lapply(list(vec1, vec2), my_fun)
      data.frame(do.call(rbind, row_list))
      

      输出:

        AA BB CC
      1  2  1  3
      2  4  3  5
      

      【讨论】:

        猜你喜欢
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多