我有一个小标题或数据帧的列表(每个小标题或列表中都有一个名称),我想:(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)
我需要使用多个列在更长的列表中执行此操作,因此对每个小标题中的每个列分别执行操作是不可行的。
答案 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
希望这会有所帮助!