如何使用R语言apply函数处理信用卡积分矩阵的超限额扣减操作?兼论purrr::map的适用性
信用卡积分调整:apply函数实现及purrr::map适用性解答
没问题,我来帮你搞定这个信用卡积分调整的需求,顺便聊聊purrr::map的使用可能性~
使用apply函数实现积分调整
我们可以利用apply()按行处理矩阵mat1,完美匹配你按信用卡(每行)调整积分的需求。核心逻辑很清晰:对每张卡,先找到累计消费超限额的月份,再给这些月份的积分扣减对应分值;如果卡片限额是NA,就直接保留原积分。
具体代码如下:
# 定义单张信用卡的积分调整函数 adjust_points <- function(row, limit, pen, cum_spend) { # 处理限额为NA的情况,直接返回原积分 if (is.na(limit)) { return(row) } # 定位累计消费超限额的月份索引 over_limit_months <- which(cum_spend > limit) # 对超限额月份的积分扣减对应分值 row[over_limit_months] <- row[over_limit_months] - pen return(row) } # 用apply按行处理矩阵,最后转置恢复原结构 adjusted_mat1 <- t(apply(mat1, MARGIN = 1, FUN = adjust_points, limit = spend_limit, pen = penalty, cum_spend = cum_spend_v))
这里用t()转置是因为apply()默认会把每行的处理结果转成列,转置后就能回到原矩阵的行结构啦。你可以验证第1张卡的结果,会和你给出的示例完全一致——第11、12月积分各减700。
purrr::map是否适用于该场景?
答案是完全可以用,只是需要先把矩阵转换成map友好的结构。因为map系列函数更擅长处理列表,我们可以先把矩阵的每一行拆成列表元素,处理完成后再重新组合成矩阵。
给你两种实现方式:
方式一:用map2关联行和索引
library(purrr) # 把矩阵按行拆分成列表,然后逐个处理 adjusted_list <- map2( .x = split(mat1, row(mat1)), # 将矩阵拆分为每行一个元素的列表 .y = seq_along(spend_limit), ~ { current_limit <- spend_limit[.y] current_penalty <- penalty[.y] if (is.na(current_limit)) { return(.x) } # 找到超限额月份 over_idx <- which(cum_spend_v > current_limit) .x[over_idx] <- .x[over_idx] - current_penalty .x } ) # 把处理后的列表重新组合成矩阵 adjusted_mat1_map <- do.call(rbind, adjusted_list)
方式二:用pmap同时传递所有参数
# 用pmap一次性传递行、限额、扣减分值三个参数 adjusted_list_pmap <- pmap( .l = list( row = split(mat1, row(mat1)), limit = spend_limit, pen = penalty ), ~ { row <- ..1 limit <- ..2 pen <- ..3 if (is.na(limit)) return(row) over_idx <- which(cum_spend_v > limit) row[over_idx] <- row[over_idx] - pen row } ) adjusted_mat1_pmap <- do.call(rbind, adjusted_list_pmap)
所以purrr::map并不是无法操作矩阵,只是需要多一步拆分和重组的操作。如果你习惯tidyverse的工作流,这种方式同样高效。
内容的提问来源于stack exchange,提问作者ixodid
相关产品推荐
相关产品推荐

