R语言按$拆分数据框价格列 动态生成对应数量新列
问题说明
数据框prices列存储爬取得到的价格数据,每行可包含多个带$前缀的价格,示例数据:
prices $1,50 $1,20 $1,50 $1,75 $1,25 $1,35
需要按$拆分价格生成独立列,自动适配不同数据集中不固定的价格数量,拆分后移除$符号,缺失值填充NA,预期输出:
prices price1 price2 price3 $1,50 $1,20 1,50 1,20 NA $1,50 1,50 NA NA $1,75 $1,25 $1,35 1,75 1,25 1,35
已尝试的方案存在两个明确问题:
- 直接使用
str_split(prices, pattern = '[$]')拆分,会因为字符串首字符是$,导致拆分后每个向量首元素为空字符串 - 使用
separate(prices, sep = '[$]', into = ...)需要提前手动指定拆分后的列数,无法封装为通用函数适配价格数量不固定的不同数据集。
解决方案
核心处理逻辑:
- 拆分前先移除每行开头的
$,从根源避免拆分出空字符串 - 动态统计当前数据集单条记录包含的最大价格数,自动生成对应数量的列,无需手动预设列数
Tidyverse 实现(推荐)
可直接封装为通用函数复用:
library(tidyverse) split_price_cols <- function(df, target_col = "prices") { df %>% mutate( # 移除行首$后,按「空格+$」规则拆分价格 price_parts = str_remove(!!sym(target_col), "^\\$") %>% str_split("\\s\\$"), # 统计当前数据最多包含多少个价格 max_col = max(map_dbl(price_parts, length)) ) %>% # 把列表列拆分为独立列 unnest_wider(price_parts, names_sep = "") %>% # 自动重命名列 rename_with(~paste0("price", seq_len(unique(.$max_col))), starts_with("price_parts")) %>% select(-max_col) }
测试效果:
# 构造测试数据 test_df <- tibble( prices = c("$1,50 $1,20", "$1,50", "$1,75 $1,25 $1,35") ) split_price_cols(test_df)
输出完全匹配预期:
# A tibble: 3 × 4 prices price1 price2 price3 <chr> <chr> <chr> <chr> 1 $1,50 $1,20 1,50 1,20 NA 2 $1,50 1,50 NA NA 3 $1,75 $1,25 $1,35 1,75 1,25 1,35
Base R 实现
无需加载第三方包的实现方式:
split_price_cols_base <- function(df, target_col = "prices") { # 拆分价格 split_res <- lapply(df[[target_col]], function(x) { strsplit(sub("^\\$", "", x), "\\s\\$")[[1]] }) # 计算需要生成的最大列数 max_col_num <- max(lengths(split_res)) # 对齐长度,缺失值填NA price_mat <- do.call(rbind, lapply(split_res, function(x) { c(x, rep(NA, max_col_num - length(x))) })) colnames(price_mat) <- paste0("price", seq_len(max_col_num)) # 合并回原数据框 cbind(df, price_mat) }
内容的提问来源于stack exchange,提问作者dvera
相关产品推荐
相关产品推荐

