Select tibbles 列表中的变量使用每个 tibble 中的名称

Select variables from list of tibbles using names in each tibble

我有一个 tibbles 或数据框列表(列表中每个都有一个名称),我想:(1) 在每个 tibble 中使用以下变量创建具有相同名称 long.col 的新列不同的名字; (2) 通过从另一个 tibble 匹配每个 tibble 中的键链接 tibble 名称和列名来完成此操作,最后; (3) 在每个小标题中为所有新创建的具有相同名称 long.col 的列绑定行,并标识它们来自的原始小标题。

我想最好使用 tidyverse 函数来执行此操作。这是两者的一个例子:a)tibbles列表; b) 在每个

中将 tibble 名称和变量标识为 select 的关键 tibble
df1 <- tibble(v1 = c(rep("A", 5), rep("B", 5)),
          v2 = 1:10)
df2 <- tibble(v1 = c(rep("C", 6), rep("D", 6)),
          v3 = 11:22)
df3 <- tibble(v1 = c(rep("E", 4), rep("F", 4)),
          v4 = 23:30)

list.df <- list(df1, df2, df3)
names(list.df) <- c("data1", "data2", "data3")

key <- tibble(data = c("data1", "data2", "data3"),
          vars = c("v2", "v3", "v4"))

最终输出应如下所示:

 final.df <- tibble(data = c(rep("data1", 10), rep("data2", 12), rep("data3", 8)),
               long.col = 1:30)

我需要在一个更长的列表中使用多列来执行此操作,因此对于每个小标题中的每一列单独执行此操作是不可行的。

你可以在这里使用map2

library(purrr)
library(tibble)
out <- map2_df(.x = list.df,
               .y = names(list.df),
               .f = ~ {
                 temp <- key[["vars"]][key[['data']] == .y]
                 tibble(data = .y, long.col = .x[[temp]])
                 })

检查输出

identical(final.df, out)
#[1] TRUE

您所陈述的问题的第一步是从键 table 中动态选取变量名称,并在相应的数据框中分配值。这可以通过首先定义一个函数来完成,该函数 returns 基于数据框的基本变量名称(对于 long.col)。

getBaseVar <- function(dfName, keyTibble){
  varToBeTransformed <- keyTibble %>% dplyr::filter(data == (!!dfName)) %>% 
                       dplyr::select(vars) %>% dplyr::first() %>% 
                         rlang::sym(.)
  return(varToBeTransformed)

}

这个函数returns需要变量名作为符号。然后可以将其传递给 dplyr::mutate 函数。为了对列表中存在的所有数据框动态执行此操作,我们将命名的数据框列表传递给 purrr::imap 函数,通过该函数列表元素(在您的情况下为数据框)和列表元素的名称都可以被访问。

list.df.transformed <- purrr::imap(list.df, function(df, name){
   df %>% dplyr::mutate( long.col := !!getBaseVar(name, key))
})

最后,您需要的输出可以通过再次将此转换数据帧列表传递给 purrr::imap 并提取必要的数据(即 long.col 列和带有重复的变量数据框名称的值)。提取后,将其传递给dplyr::bind_rows函数returns所需的数据框。

final.df <- tibble(data = character(), long.col = numeric()) 
purrr::imap(list.df.transformed, function(df, name){
    repeatedNameCol <- tibble(data = rep(name, nrow(df)))
    dataToBind <- df %>% dplyr::select(long.col) %>% 
                     dplyr::bind_cols(repeatedNameCol)
    return(dataToBind)
}) %>% dplyr::bind_rows(.) -> final.df

希望对您有所帮助!