如何将R语言DataFrame所有列按字符位置拆分为两半?
批量拆分R语言DataFrame中所有6位字符列为前后3位
问题背景
我有一个R语言DataFrame,所有列的内容都是6位字符,示例数据如下:
df = data.frame("A" = c("001000","101010","131313"), "B" = c("121212","434343","737373"), "C" = c("555555","959595","383838"))
原始DataFrame输出:
A B C 1 001000 121212 555555 2 101010 434343 959595 3 131313 737373 383838
需要将每一列从中间拆分为两列,分别包含前3位和后3位字符,目标结果示例(新列名无要求,保持原有顺序即可):
final_df = data.frame("A" = c("001","101","131"),"A1" = c("000","010","313"), "B" = c("121","434","737"),"B1" = c("212","343","373"), "C" = c("555","959","383"),"C1" = c("555","595","838"))
目标DataFrame输出:
A A1 B B1 C C1 1 001 000 121 212 555 555 2 101 010 434 343 959 595 3 131 313 737 373 383 838
之前用transform()或separate()处理单列时需要指定新列名,不知道如何批量处理所有列。
解决方案
方法1:tidyverse工具包(dplyr + tidyr)
用across()批量对所有列应用拆分逻辑,自动生成新列名:
library(dplyr) library(tidyr) # 简洁版:直接拆分所有列 final_df <- df %>% separate(across(everything()), into = ~paste0(c(., paste0(., "1"))), sep = 3, remove = TRUE)
sep=3:指定从第3个字符后拆分into:通过paste0自动生成原列名和原列名+1的新列名remove=TRUE:删除原始列,只保留拆分后的新列
如果需要更灵活的列名定义,也可以用mutate结合across:
final_df <- df %>% mutate(across(everything(), list( first3 = ~substr(., 1, 3), last3 = ~substr(., 4, 6) ))) %>% # 调整列顺序,让原列对应的拆分列相邻 select(order(str_replace_all(colnames(.), "_.*", "")))
方法2:Base R 原生实现(无需额外包)
通过循环遍历每一列,拆分后合并结果:
final_df <- data.frame() for(col in colnames(df)){ # 提取当前列的前3位和后3位 first_part <- substr(df[[col]], 1, 3) last_part <- substr(df[[col]], 4, 6) # 合并到结果DataFrame final_df <- cbind(final_df, first_part, last_part) # 给新列命名 colnames(final_df)[(ncol(final_df)-1):ncol(final_df)] <- c(col, paste0(col, "1")) } # 重置行名 rownames(final_df) <- NULL
方法3:data.table高效处理(适合大数据集)
如果处理的是大型数据集,data.table的方法速度更快:
library(data.table) # 转换为data.table格式 setDT(df) # 批量拆分所有列 final_df <- df[, lapply(.SD, function(x) .(substr(x,1,3), substr(x,4,6)))] # 重命名列 setnames(final_df, paste0(rep(colnames(df), each=2), c("", "1")))
内容的提问来源于stack exchange,提问作者Evelyn Abbott
相关产品推荐
相关产品推荐

