【问题标题】:Use apply functions with matrices and multiple vectors对矩阵和多个向量使用应用函数
【发布时间】:2021-09-19 02:57:16
【问题描述】:

假设我有 10 张不同的信用卡,并根据每月的消费模式计算了每张信用卡的奖励积分。

矩阵中的每一行,mat1 代表一张不同的信用卡。 每列是一年中的一个月。

持卡人每月花费 7275 美元。 但是,如果您每年花费超过一定金额,则会受到处罚。每张卡可能有不同的限制和惩罚。

卡的限制和处罚在spend_limitpenalty 中给出。 每个向量中的第 n 个元素对应于矩阵中的行顺序相同的第 n 个信用卡。

例如,该持卡人的累计消费为:

> cum_spend_v
 [1]  7275 14550 21825 29100 36375 43650 50925 58200 65475 72750 80025 87300

消费限额为:

spend_limit <- c(80000, 80000, 200000, 10000, 80000, 6000, 40000, 6000, 4000, NA)

所以对于卡#1 mat1 row1 列 11 和 12 需要调整卡#1 的 700 分罚分:


            1        2        3        4        5        6        7        8        9       10       11       12
 [1,]  9475.00  9475.00 30725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10025.00 10025.00

如何使用 R 的应用函数之一执行这些操作? purrr:map 是不是因为它不直接对矩阵进行操作,所以不在图片范围内?

R 脚本

mat1 <- 
structure(c(9475, 8375, 12808.75, 10018.75, 9475, 5337.5, 5583.2995, 
            5337.5, 5583.2995, 0, 9475, 8375, 12808.75, 10018.75, 9475, 5337.5, 
            5583.2995, 5337.5, 5583.2995, 0, 30725, 18375, 15308.75, 32518.75, 
            30725, 12837.5, 15583.2995, 5337.5, 15583.2995, 0, 10725, 8375, 
            15308.75, 12518.75, 10725, 5337.5, 5583.2995, 5337.5, 5583.2995, 
            0, 10725, 8375, 15308.75, 12518.75, 10725, 5337.5, 5583.2995, 
            5337.5, 5583.2995, 0, 10725, 8375, 15308.75, 12518.75, 10725, 
            5337.5, 5583.2995, 5337.5, 5583.2995, 0, 10725, 8375, 15308.75, 
            12518.75, 10725, 5337.5, 5583.2995, 5337.5, 5583.2995, 0, 10725, 
            8375, 15308.75, 12518.75, 10725, 5337.5, 5583.2995, 5337.5, 5583.2995, 
            0, 10725, 8375, 15308.75, 12518.75, 10725, 5337.5, 5583.2995, 
            5337.5, 5583.2995, 0, 10725, 8375, 15308.75, 12518.75, 10725, 
            5337.5, 5583.2995, 5337.5, 5583.2995, 0, 10725, 8375, 15308.75, 
            12518.75, 10725, 5337.5, 5583.2995, 5337.5, 5583.2995, 0, 10725, 
            8375, 15308.75, 12518.75, 10725, 5337.5, 5583.2995, 5337.5, 5583.2995, 
            0), .Dim = c(10L, 12L), .Dimnames = list(NULL, c("1", "2", "3", 
                                                             "4", "5", "6", "7", "8", "9", "10", "11", "12")))
# Monthly spending
monthly_spend <- 7275
cum_spend_v <- cumsum(rep(monthly_spend, 12))

# Spending limit for different cards
spend_limit <- c(80000, 80000, 200000, 10000, 80000, 6000, 40000, 6000, 4000, NA)

# Penalty for overspending
penalty <- c(700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600)



which(cum_spend_v > spend_limit[1])

【问题讨论】:

    标签: r apply purrr


    【解决方案1】:

    您可以使用penalty 以及行中的卡片和列中的月份来制作矩阵,类似于mat1。然后,使用matrixStats 包的rowCumsums,只需减去子集p 的两个矩阵,其中每张卡的累计支出总和超过spend_limit 向量(不得包含任何NA)。

    您确实只是提供了一张卡的每月支出,所以我将其扩展一点。

    spend <- c(7275, 8646, 6710, 7638, 7908, 7679, 7169, 8787, 7180, 0)
    M_spend <- matrix(spend, 10, 12)
    
    penalty <- c(700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600)
    M_penalty <- matrix(penalty, 10, 12)
    
    spend_limit <- c(80000, 80000, 200000, 10000, 80000, 6000, 40000, 6000, 4000, 0)
    
    p <- rowCumsums(M_spend) > spend_limit
    mat1[p] <- mat1[p] - M_penalty[p] 
    

    结果

    mat1
    #              1        2        3        4        5        6        7        8        9       10       11       12
    #  [1,]  9475.00  9475.00 30725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10025.00 10025.00
    #  [2,]  8375.00  8375.00 18375.00  8375.00  8375.00  8375.00  8375.00  8375.00  8375.00  7575.00  7575.00  7575.00
    #  [3,] 12808.75 12808.75 15308.75 15308.75 15308.75 15308.75 15308.75 15308.75 15308.75 15308.75 15308.75 15308.75
    #  [4,] 10018.75  9018.75 31518.75 11518.75 11518.75 11518.75 11518.75 11518.75 11518.75 11518.75 11518.75 11518.75
    #  [5,]  9475.00  9475.00 30725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00 10725.00  9625.00  9625.00
    #  [6,]  4137.50  4137.50 11637.50  4137.50  4137.50  4137.50  4137.50  4137.50  4137.50  4137.50  4137.50  4137.50
    #  [7,]  5583.30  5583.30 15583.30  5583.30  5583.30  4283.30  4283.30  4283.30  4283.30  4283.30  4283.30  4283.30
    #  [8,]  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50  3937.50
    #  [9,]  4083.30  4083.30 14083.30  4083.30  4083.30  4083.30  4083.30  4083.30  4083.30  4083.30  4083.30  4083.30
    # [10,]     0.00     0.00     0.00     0.00     0.00     0.00     0.00     0.00     0.00     0.00     0.00     0.00
    

    如果pTRUE,你可以想象它就像叠加两个矩阵并减去叠加的单元格。

    注意:您也可以使用apply(m, 1, cumsum) 代替rowCumsums(m),但速度较慢。

    【讨论】:

    • 我认为您的答案不太正确,因为 mat1 是奖励积分矩阵,而不是支出矩阵。所以这行不通:rowCumsums(mat1) >pend_limit
    • @ixodid 我想出了一个支出矩阵给你,请检查更新。
    猜你喜欢
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    • 2020-06-23
    • 2011-06-20
    • 2015-07-31
    • 1970-01-01
    • 2019-08-25
    相关资源
    最近更新 更多