【问题标题】:How to assign variable to data frame based on year? Dplyr: case_when issues如何根据年份将变量分配给数据框? Dplyr:case_when 问题
【发布时间】:2021-09-21 09:02:07
【问题描述】:

我的问题与我自己无法根据年份为我的数据框分配折扣率(变量)有关。

我有一个包含客户详细信息的数据框,然后是按年份划分的每种类型(M、R 和 O)的折扣率,其中 1=2019 和 2=2020 等。示例数据如下:

df1 <- data.frame(ID = c(1, 2, 3, 4, 5),
                  customer_type = c('M', 'R', 'O', 'M', 'M'),
                  year = c(1, 1, 2, 2, 3))

现在我有 2019 年到 2023 年 5 年的折扣率,例如:

discount_rates <- data.frame(year = c(2019, 2020, 2021, 2022, 2023),
                  metro_M = c(0.1,0.2,0.3,0.3,0.1),
                  regional_R = c(0.01, 0.1, 0.02, 0.11, 0.09),
                  overseas_O = c(0.2, 0.3, 0.4, 0.5, 0.5))

我想要做的是将相关年份的折扣率添加到 df1。

示例输出如下: |编号 |customer_type|year|discount_rate| |----|-------------|----|-------------| | 1 | M |1 |0.1 | | 2 | R |1 |0.01 | | 3 | O |2 |0.3 | | 4 | M |2 |0.2 | | 5 | M |3 |0.3 |

我尝试过的是使用 case_when 语句:

df1$discount_rate <-
  case_when(
    df1$customer_type == "M" ~ metro_M[[df1$year]],
    df1$customer_type == "O" ~ overseas_O[[df1$year]],
    df1$customer_type == "R" ~ regional_R[[df1$year]],
    TRUE ~ 0
  )

但是这样我得到错误:“尝试在vectorIndex中选择多个元素”

我对此感到困惑,如果其他人知道更好的方法,我将不胜感激?

【问题讨论】:

    标签: r dataframe dplyr variable-assignment


    【解决方案1】:

    您可以将discount_rates df 转换为长格式并使用left_join 分配折扣率,如下所示:

    library(dplyr)
    library(tidyr)
    
    discount_rates_long <- discount_rates %>% 
      pivot_longer(-year, values_to = "discount_rate") %>% 
      separate(name, into = c("label", "customer_type"))
    
    df1 %>% 
      mutate(year = 2018 + year) %>% 
      left_join(discount_rates_long, by = c("year", "customer_type"))
    #>   ID customer_type year    label discount_rate
    #> 1  1             M 2019    metro          0.10
    #> 2  2             R 2019 regional          0.01
    #> 3  3             O 2020 overseas          0.30
    #> 4  4             M 2020    metro          0.20
    #> 5  5             M 2021    metro          0.30
    

    【讨论】:

    • 非常感谢 Stefan,我最初对使用左连接犹豫不决,因为我认为这可能需要一段时间(500k 行),但这出奇的快!
    【解决方案2】:
    library(tidyverse)
    
    df1 <- data.frame(ID = c(1, 2, 3, 4, 5),
                      customer_type = c('M', 'R', 'O', 'M', 'M'),
                      year = c(1, 1, 2, 2, 3))
    
    discount_rates <- data.frame(year = c(2019, 2020, 2021, 2022, 2023),
                                 metro_M = c(0.1,0.2,0.3,0.3,0.1),
                                 regional_R = c(0.01, 0.1, 0.02, 0.11, 0.09),
                                 overseas_O = c(0.2, 0.3, 0.4, 0.5, 0.5))
    
    
    df1 <- df1 %>% mutate(year=2018+year)
    
    df2 <- left_join(df1,discount_rates,by="year")
    
    df2 <- df2 %>%
      mutate(discount_rate = case_when(
        customer_type == "M" ~ metro_M,
        customer_type == "O" ~ overseas_O,
        customer_type == "R" ~ regional_R,
        TRUE ~ 0))
    

    结果:

      ID customer_type year metro_M regional_R overseas_O discount_rate
    1  1             M 2019     0.1       0.01        0.2          0.10
    2  2             R 2019     0.1       0.01        0.2          0.01
    3  3             O 2020     0.2       0.10        0.3          0.30
    4  4             M 2020     0.2       0.10        0.3          0.20
    5  5             M 2021     0.3       0.02        0.4          0.30
    

    【讨论】:

      猜你喜欢
      • 2018-12-06
      • 1970-01-01
      • 2023-03-31
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 2016-10-24
      相关资源
      最近更新 更多