R语言如何提取字符串中%标记的百分比并计算数据框列平均值
问题说明
需要从数据框字符串类型的rates列中提取所有带%标识的百分比数值,按行计算简单算术平均值,结果存入新增的average列。
原测试数据与错误代码如下:
rates <-c("7.5% ( 01-01 to 31-01 ) ; 0% ( 01-02 to 30-06 ) ; 7.5% ( 01-07 to 31-12 )", "0% (01 FEB - 30 JUN); 3.70% (01-01 to 31-01) ; 3.70% (01-07 to 31-12)") product <-c("001","002") df <- data.frame(product,rates) # 原错误实现 df$average <- average(as.numeric(grepl("\\d+\\%",rates)))
预期运行后average列结果为c(5,2.5)。
原代码错误点
- 函数误用:
grepl()仅返回是否匹配到规则的逻辑值(TRUE/FALSE),无法提取匹配到的具体百分比数值;R基础环境中不存在average()函数,计算算术均值需使用mean() - 正则缺陷:原正则
\\d+\\%仅能匹配整数百分比,无法识别带小数位的百分比值(如7.5%、3.70%) - 缺少逐行处理逻辑:原代码直接对整列操作,没有对每个单元格内的字符串单独完成提取、转数值、求均值的流程
正确实现方案
推荐使用stringr包的字符串提取函数,逻辑清晰易维护,代码如下:
# 若未安装stringr先运行 install.packages("stringr") library(stringr) df$average <- sapply( str_extract_all(df$rates, "\\d+\\.?\\d*(?=%)"), # 正向预查匹配%前的数字(支持整数、小数) function(x) mean(as.numeric(x)) # 对每行提取到的数字转数值后求均值 )
如果不想依赖第三方包,也可以用基础R实现:
df$average <- sapply( regmatches(df$rates, gregexpr("\\d+\\.?\\d*(?=%)", df$rates, perl = TRUE)), function(x) mean(as.numeric(x)) )
运行结果
运行代码后得到的数据框内容如下,第二行均值约为2.47,与预期给出的2.5为近似值差异:
> df product rates average 1 001 7.5% ( 01-01 to 31-01 ) ; 0% ( 01-02 to 30-06 ) ; 7.5% ( 01-07 to 31-12 ) 5.000000 2 002 0% (01 FEB - 30 JUN); 3.70% (01-01 to 31-01) ; 3.70% (01-07 to 31-12) 2.466667
如果需要和预期结果完全一致,可以在计算后对结果做四舍五入处理:
df$average <- round(df$average, 1)
处理后第二行结果即为2.5。
内容的提问来源于stack exchange,提问作者melange164
相关产品推荐
相关产品推荐

