如何使用字典有效地附加数据集(R/dplyr)? / 如何合并 'all columns with duplicate names'?
How to effectively append datasets using a dictionary (with R/dplyr)? / How to coalesce 'all columns with duplicate names'?
我有一系列数据集和一本字典可以将它们整合在一起。但我正在努力弄清楚如何自动执行此操作。
假设这个数据和字典(实际的要长得多,因此我想自动化):
mtcarsA <- mtcars[1:5,] %>% rename(mpgA = mpg, cyl_A = cyl) %>% as_tibble()
mtcarsB <- mtcars[6:10,] %>% rename(mpg_B = mpg, B_cyl = cyl) %>% as_tibble()
dic <- tibble(true_name = c("mpg_true", "cyl_true"),
nameA = c("mpgA", "cyl_A"),
nameB = c("mpg_B", "B_cyl")
)
我希望将这些数据集(来自 A 年和 B 年)相互附加,然后将名称更改或合并为 'true_name' 值。
我可以将数据集合并到 mtcars_all
,然后我尝试用字典重新编码列名,如下所示
mtcars_all <- bind_rows((mtcarsA, mtcarsB)
recode_colname <- function(df, tn=dic$true_name, fname){
colnames(df) <- dplyr::recode(colnames(df),
!!!setNames(as.character(tn), fname))
return(df)
}
mtcars_all <- mtcars_all %>%
recode_colname(fname=dic$nameA) %>%
recode_colname(fname=dic$nameB)
但后来我得到 重复 列。当然,我可以按名称合并这些重复的列中的每一个,但在我的实际情况中会有 很多 ,所以我想自动化 'coalesce all columns with duplicate names'.
我在这里给出了整个问题,因为也许有人对 'using a data dictionary' 也有更好的解决方案。
您可以创建命名向量来替换列名。
library(tidyverse)
pmap(dic, ~setNames(..1, paste0(c(..2, ..3), collapse = '|'))) %>%
flatten_chr() -> val
val
# mpgA|mpg_B cyl_A|B_cyl
# "mpg_true" "cyl_true"
并将其应用于数据帧列表并合并它们。
list(mtcarsA,mtcarsB) %>%
map_df(function(x) x %>% rename_with(~str_replace_all(.x, val)))
# mpg_true cyl_true disp hp drat wt qsec vs am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
# 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
# 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
# 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
# 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
# 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
# 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
# 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
# 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
我有一系列数据集和一本字典可以将它们整合在一起。但我正在努力弄清楚如何自动执行此操作。
假设这个数据和字典(实际的要长得多,因此我想自动化):
mtcarsA <- mtcars[1:5,] %>% rename(mpgA = mpg, cyl_A = cyl) %>% as_tibble()
mtcarsB <- mtcars[6:10,] %>% rename(mpg_B = mpg, B_cyl = cyl) %>% as_tibble()
dic <- tibble(true_name = c("mpg_true", "cyl_true"),
nameA = c("mpgA", "cyl_A"),
nameB = c("mpg_B", "B_cyl")
)
我希望将这些数据集(来自 A 年和 B 年)相互附加,然后将名称更改或合并为 'true_name' 值。
我可以将数据集合并到 mtcars_all
,然后我尝试用字典重新编码列名,如下所示
mtcars_all <- bind_rows((mtcarsA, mtcarsB)
recode_colname <- function(df, tn=dic$true_name, fname){
colnames(df) <- dplyr::recode(colnames(df),
!!!setNames(as.character(tn), fname))
return(df)
}
mtcars_all <- mtcars_all %>%
recode_colname(fname=dic$nameA) %>%
recode_colname(fname=dic$nameB)
但后来我得到 重复 列。当然,我可以按名称合并这些重复的列中的每一个,但在我的实际情况中会有 很多 ,所以我想自动化 'coalesce all columns with duplicate names'.
我在这里给出了整个问题,因为也许有人对 'using a data dictionary' 也有更好的解决方案。
您可以创建命名向量来替换列名。
library(tidyverse)
pmap(dic, ~setNames(..1, paste0(c(..2, ..3), collapse = '|'))) %>%
flatten_chr() -> val
val
# mpgA|mpg_B cyl_A|B_cyl
# "mpg_true" "cyl_true"
并将其应用于数据帧列表并合并它们。
list(mtcarsA,mtcarsB) %>%
map_df(function(x) x %>% rename_with(~str_replace_all(.x, val)))
# mpg_true cyl_true disp hp drat wt qsec vs am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
# 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
# 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
# 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
# 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
# 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
# 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
# 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
# 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4