R语言对比dataframe列与阈值向量 实现小值置0大值封顶
R 按列匹配阈值处理DataFrame数值方案
处理规则
- 对数据框逐列做双阈值处理:
- 数值 < 对应列下限阈值:置为0
- 数值 > 对应列上限阈值:截断为对应列上限值
- 阈值向量顺序和数据框列顺序一一对应
示例输入
# 原始数据 A=structure(list(V1 = c(0.108762394171208, 0.462799827801064, 0.391699776984751, 0.701799504924566), V2 = c(0.226724285865203, 0.163136613089591, 0.428917320212349, 0.538211710518226), V3 = c(0.929441494401544, 0.0767909574788064, 0.144388129469007, 0.555204615229741)), class = "data.frame", row.names = c(NA, -4L)) # 各列下限阈值,顺序对应V1/V2/V3 Amin=c(0.15,0.12,0.08) # 各列上限阈值,顺序对应V1/V2/V3 Amax=c(0.65,0.9,0.8)
期望输出
> A_res V1 V2 V3 1 0.0000000 0.2267243 0.8000000 2 0.4627998 0.1631366 0.0000000 3 0.3916998 0.4289173 0.1443881 4 0.6500000 0.5382117 0.5552046
问题根源
之前上限截断逻辑匹配错位,是因为R中向量和数据框做运算时,默认按列优先顺序循环展开向量:长度为3的阈值向量会被循环填充为12个元素(4行*3列),按列依次排布,导致列和阈值对应关系错乱。
实现代码
基础R实现(无依赖,效率最高)
用mapply逐列传入对应列的数值、下限、上限阈值,从根源避免匹配错位:
A_res <- as.data.frame( mapply(function(col_val, low_thres, high_thres) { # 先处理下限置0 tmp <- ifelse(col_val < low_thres, 0, col_val) # 再处理上限截断 tmp <- pmin(tmp, high_thres) return(tmp) }, A, Amin, Amax) )
如果习惯用下标赋值的写法,需要先把阈值转为按行重复的同维度矩阵,保证每行的每一列都对应到正确阈值:
A_res <- A # 构造和A同维度的阈值矩阵,按行填充保证列匹配 low_mat <- matrix(Amin, nrow = nrow(A), ncol = ncol(A), byrow = TRUE) high_mat <- matrix(Amax, nrow = nrow(A), ncol = ncol(A), byrow = TRUE) # 下限置0 A_res[A < low_mat] <- 0 # 上限截断 A_res[A_res > high_mat] <- high_mat[A_res > high_mat]
Tidyverse实现(适合管道工作流)
加载dplyr包,用across逐列处理,通过列位置匹配对应阈值:
library(dplyr) A_res <- A %>% mutate(across( everything(), ~ case_when( .x < Amin[which(names(A) == cur_column())] ~ 0, .x > Amax[which(names(A) == cur_column())] ~ Amax[which(names(A) == cur_column())], TRUE ~ .x ) ))
结果校验
运行上述任意一段代码,输出结果均符合预期:
> print(A_res, digits = 7) V1 V2 V3 1 0.0000000 0.2267243 0.8000000 2 0.4627998 0.1631366 0.0000000 3 0.3916998 0.4289173 0.1443881 4 0.6500000 0.5382117 0.5552046
内容的提问来源于stack exchange,提问作者Osvaldo Assunção
相关产品推荐
相关产品推荐

