拆分DataFrame中Salary列时的多字符货币符号兼容问题
处理Salary列中多长度货币符号的拆分问题
我明白你遇到的痛点了——固定位置的拆分方法在面对不同长度的货币符号时完全失效,毕竟有的是单字符的₹,有的是多字符的AFN。别担心,咱们换个思路,用正则表达式匹配内容模式来解决,这比硬卡字符位置靠谱多了。
先把你的示例DataFrame放出来,方便大家参考:
sample_df <- structure(list(Company.Name = c("Ample Softech System", "Ziff Davis LLC", "IIM Kozhikkode", "Perennial", "Irupar Sociedad Cooperativa", "md", ""), Job.Title = c("Data Analyst", "Data Analyst", "Data Analyst", "Data Analyst", "Data Analyst", "Data Analyst", "Data Analyst" ), Salaries.Reported = c(1L, 1L, 1L, 1L, 1L, 1L, 1L), Location = c("Pune", "Pune", "Pune", "Pune", "Pune", "Pune", "Pune"), Salary = c("₹35,563/mo", "₹5,21,474/yr", "₹7,64,702/yr", "₹16,123/mo", "₹6,04,401/yr", "AFN 1,56,179/yr", "₹23,500/mo")), row.names = 2274:2280, class = "data.frame")
方法1:用tidyr::extract一步拆分(推荐)
extract函数支持用正则分组来拆分列,刚好能适配你的场景。我们的正则会精准匹配三个部分:
- 开头的字母/货币符号(不管长度)
- 中间的数字+逗号金额
- 结尾的周期标识(mo/yr)
代码如下:
library(tidyr) library(dplyr) sample_df_cleaned <- sample_df %>% extract( col = Salary, into = c("Currency_symbol", "Salary_amount", "Periodicity"), # 正则分组:字母符号 + 可选空格 + 数字金额 + / + 周期 regex = "^([A-Za-z₹]+)\\s*([0-9,]+)/([a-z]+)$", remove = TRUE ) %>% # 可选:把金额转换成数值型(去掉逗号) mutate(Salary_amount = as.numeric(gsub(",", "", Salary_amount))) print(sample_df_cleaned)
解释下正则的逻辑:
^([A-Za-z₹]+):匹配开头的字母或₹符号(覆盖单字符和多字符货币符号)\\s*:匹配货币符号和金额之间的可选空格(比如AFN后面的空格)([0-9,]+):匹配数字和逗号组成的金额部分/([a-z]+)$:匹配/后面的小写字母周期,直到字符串结尾
方法2:用stringr逐个提取(更灵活)
如果你想更清晰地控制每一部分的提取,可以用stringr包的函数分别捕获每一段内容:
library(stringr) library(dplyr) sample_df_cleaned <- sample_df %>% mutate( # 提取开头的货币符号(字母或₹) Currency_symbol = str_extract(Salary, "^[A-Za-z₹]+"), # 提取数字+逗号的金额部分 Salary_amount = str_extract(Salary, "[0-9,]+"), # 提取结尾的周期标识 Periodicity = str_extract(Salary, "[a-z]+$") ) %>% # 移除原Salary列 select(-Salary) %>% # 转换金额为数值型 mutate(Salary_amount = as.numeric(gsub(",", "", Salary_amount))) print(sample_df_cleaned)
这两种方法都能完美处理单字符和多字符货币符号的情况,再也不用纠结固定的字符位置了!
内容的提问来源于stack exchange,提问作者classy_BLINK
相关产品推荐
相关产品推荐

