使用每个小标题中的名称从小标题列表中选择变量

时间:2018-11-25 04:49:48

标签: r list select data-binding tibble

我有一个小标题或数据帧的列表(每个小标题或列表中都有一个名称),我想:(1)在每个小标题中,使用具有不同名称的变量创建具有相同名称long.col的新列; (2)通过匹配另一个小词,并最终在每个小词中使用键链接小词名称和列名来进行匹配; (3)在每个小标题中为所有具有相同名称long.col的所有新创建的列绑定行,并标识它们来自的原始小标题。

我想最好使用tidyverse函数来做到这一点。这是两个示例:a)小标题列表; b)关键小标题,标识小标题名称和变量,以便在每个小标题中选择

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)

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

2 个答案:

答案 0 :(得分:2)

您可以在此处使用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

答案 1 :(得分:0)

您所说的问题的第一步是从密钥表中动态选择变量名称,并在相应的数据框中分配值。这可以通过首先定义一个函数来完成,该函数根据数据帧返回基本变量名(对于long.col)。

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

}

此函数返回所需的变量名称作为符号。然后可以将其传递给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函数将返回所需的数据帧。

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

希望这会有所帮助!