当列名不同时如何通过选择特定列来组合多个数据框
How to combine multiple dataframes by selecting specific columns when the column names are different
我在列表 my_data
中有七个 data.frames。其中三个 data.frames 有 16 列,另外四个有 22 列。我需要将每个 data.frame 中的五列绑定到一个 data.frame (all_data
) 中。问题是我不能简单地 select 我想按名称保留的列,因为每个 data.frame 之间的名称不同(但相似)并且顺序不同。例如,我有一个 data.frame 有一个标题为 "X2012.NAICS.code" 的列,另一个有一个标题为 "X2007.NAICS.codes.and.NAICS.based.rollup.code" 的列。这些列包含相同的信息(NAICS 代码)并且需要绑定在一起。
我尝试使用的方法是:
header_cols <- c( "Geographic.area.name", "Year", "**3rd column**", "**4th column**", "**5th column**" )
all_data <- map_dfr( my_data[grepl( "^ASM", names( my_data ))], ~
.x %>%
select( header_cols ))
其中第 3、4 和 5 列是我需要的其他三个列(Year
和 Geographic.area.name
在所有 7 个 data.frames 之间是相同的)。
所有 data.frame 名称都以 "ASM" 开头,这就是 ^ASM
的用途。
更新:我目前的策略是这样
# Make object for raw column name strings (all columns of interest contain these strings in all dataframes)
name_pattern <- c( "Geographic.area.name", "Geographic Area Name")
VoS_pattern <- c( "Total.value.of.shipment", "value of shipments")
NAICS_pattern <- c( "NAICS.code", "NAICS code")
industry_pattern <- c("Meaning.of.", "Meaning of NAICS code")
relative_pattern <- c("Relative.standard.error", "Relative standard error")
header_cols <- c( "Year" )
# Part 3: binding the data into one dataframe based on the columns of interest, uniting columns that contain the same information category
# Bind the columns of interest into one dataframe
combined_data <- map_dfr( my_data[grepl( "^ASM", names( my_data ))], ~
.x %>%
select( header_cols, contains( paste0( name_pattern ) ),
contains( paste0( VoS_pattern ) ),
contains( paste0( NAICS_pattern ) ),
contains( paste0( industry_pattern ) ),
-contains ( paste0( relative_pattern) ) ))
效果很好。不幸的是,我不能使用 map_dfr
函数(或任何特定于 purrr 的函数,所以我正在寻找一种方法来使用 rbind 来做到这一点。
一个选项是在列中 select
之后使用 rename_at
标准化列名。
library(dplyr)
library(stringr)
library(purrr)
map_dfr(my_data[grep('^ASM', names(my_data))], ~
.x %>%
select(header_cols[1:2],
matches("NAICS\.(code|based\.rollup\.code)")) %>%
rename_at(matches("NAICS"), ~ str_remove(., "^X\d{4}\.")))
或 base R
使用 lapply
v1 <- c("Year", "state_name", "VoS_thousUSD", "NAICS_code", "industry")
out <- lapply(my_data[grep('^ASM', names(my_data))],
function(x) x %>%
mutate_if(is.factor, as.character) %>%
select( header_cols, contains( paste0( name_pattern ) ),
contains( paste0( VoS_pattern ) ),
contains( paste0( NAICS_pattern ) ),
contains( paste0( industry_pattern ) ),
-contains ( paste0( relative_pattern) ) ) %>%
set_names(v1))
combined_data <- do.call(rbind, out)
row.names(combined_data) <- NULL
# Make VoS numeric
combined_data_new <- combined_data %>%
dplyr::mutate( VoS_thousUSD = as.numeric( VoS_thousUSD ) )
我在列表 my_data
中有七个 data.frames。其中三个 data.frames 有 16 列,另外四个有 22 列。我需要将每个 data.frame 中的五列绑定到一个 data.frame (all_data
) 中。问题是我不能简单地 select 我想按名称保留的列,因为每个 data.frame 之间的名称不同(但相似)并且顺序不同。例如,我有一个 data.frame 有一个标题为 "X2012.NAICS.code" 的列,另一个有一个标题为 "X2007.NAICS.codes.and.NAICS.based.rollup.code" 的列。这些列包含相同的信息(NAICS 代码)并且需要绑定在一起。
我尝试使用的方法是:
header_cols <- c( "Geographic.area.name", "Year", "**3rd column**", "**4th column**", "**5th column**" )
all_data <- map_dfr( my_data[grepl( "^ASM", names( my_data ))], ~
.x %>%
select( header_cols ))
其中第 3、4 和 5 列是我需要的其他三个列(Year
和 Geographic.area.name
在所有 7 个 data.frames 之间是相同的)。
所有 data.frame 名称都以 "ASM" 开头,这就是 ^ASM
的用途。
更新:我目前的策略是这样
# Make object for raw column name strings (all columns of interest contain these strings in all dataframes)
name_pattern <- c( "Geographic.area.name", "Geographic Area Name")
VoS_pattern <- c( "Total.value.of.shipment", "value of shipments")
NAICS_pattern <- c( "NAICS.code", "NAICS code")
industry_pattern <- c("Meaning.of.", "Meaning of NAICS code")
relative_pattern <- c("Relative.standard.error", "Relative standard error")
header_cols <- c( "Year" )
# Part 3: binding the data into one dataframe based on the columns of interest, uniting columns that contain the same information category
# Bind the columns of interest into one dataframe
combined_data <- map_dfr( my_data[grepl( "^ASM", names( my_data ))], ~
.x %>%
select( header_cols, contains( paste0( name_pattern ) ),
contains( paste0( VoS_pattern ) ),
contains( paste0( NAICS_pattern ) ),
contains( paste0( industry_pattern ) ),
-contains ( paste0( relative_pattern) ) ))
效果很好。不幸的是,我不能使用 map_dfr
函数(或任何特定于 purrr 的函数,所以我正在寻找一种方法来使用 rbind 来做到这一点。
一个选项是在列中 select
之后使用 rename_at
标准化列名。
library(dplyr)
library(stringr)
library(purrr)
map_dfr(my_data[grep('^ASM', names(my_data))], ~
.x %>%
select(header_cols[1:2],
matches("NAICS\.(code|based\.rollup\.code)")) %>%
rename_at(matches("NAICS"), ~ str_remove(., "^X\d{4}\.")))
或 base R
使用 lapply
v1 <- c("Year", "state_name", "VoS_thousUSD", "NAICS_code", "industry")
out <- lapply(my_data[grep('^ASM', names(my_data))],
function(x) x %>%
mutate_if(is.factor, as.character) %>%
select( header_cols, contains( paste0( name_pattern ) ),
contains( paste0( VoS_pattern ) ),
contains( paste0( NAICS_pattern ) ),
contains( paste0( industry_pattern ) ),
-contains ( paste0( relative_pattern) ) ) %>%
set_names(v1))
combined_data <- do.call(rbind, out)
row.names(combined_data) <- NULL
# Make VoS numeric
combined_data_new <- combined_data %>%
dplyr::mutate( VoS_thousUSD = as.numeric( VoS_thousUSD ) )