【问题标题】:In R: How to extract info about valid time periods and apply it to another dataset?在 R 中:如何提取有关有效时间段的信息并将其应用于另一个数据集?
【发布时间】:2019-03-21 15:54:24
【问题描述】:

我必须要合并的数据集:

数据集 1:包含“perc”有效的时间段:

set.seed(1)

example_df <- data.frame(ID = rep(1:2, each=2),   
start = c(as.Date("2014-01-01"), as.Date("2014-03-05"), as.Date("2014-01-13"), as.Date("2014-03-15")), 
                         end = c(as.Date("2014-03-05"), as.Date("2014-04-12"), as.Date("2014-03-01"), as.Date("2014-04-02")), 
                         perc = rnorm(mean= 30, sd= 10, 4)) 

数据集 2:包含每个月的工资:

 month_start <- as.Date("2014-01-01") + months(0:3)
    month_end <-  ceiling_date(month_start, "month") - days(1)

set.seed(1)
example_df2 <-  data.frame(month_start, month_end,
                           ID = rep(1:2, each=4),
                           pay = rnorm(mean= 2000, sd= 80, 8))

我们的目标是根据每个人的工作量计算每个月的工资。重要的是要考虑 perc 的有效时间段,这可能会在一个月内发生变化。

例如:

2014 年 1 月 ID 1:支付 = 1949.884(支付)*23.73546(perc)/100

因为 perc 在整个 1 月都有效。

但是,对于 3 月,直到 5 日,perc 为 23.73546,而 3 月剩余时间的 perc 为 31.83643。

因此,

ID 1 的 2014 年 3 月:工资 = 1949.884(工资)*23.73546(perc)/100/31(3 月天数)*5 + 1949.884(工资)*31.83643(perc)/100/31(3 月天数) *26

【问题讨论】:

    标签: r time dplyr period


    【解决方案1】:

    在 2 个数据帧之间以 left_join() 开头。 ID 的每个工作期将在此ID 的每个支付月期间复制。 然后,我们连续ifelse(),您可以确定是否应该计算总月份,只计算一部分,还是根本不计算。

    library(tidyverse)
    
    result <- example_df %>% 
      left_join(example_df2, by = 'ID') %>% 
      mutate(
        TEST_MONTH = ifelse(end >= month_start & start < month_end, 1, 0), 
        TEST_DAYS  = ifelse(TEST_MONTH == 1,
                            ifelse(end > month_end,
                                   ifelse(start >= month_start, month_end - start + 1, month_end - month_start + 1), 
                                   end - month_start + 1), 
                            0),
        PAID = pay * perc/100 * TEST_DAYS / as.numeric(month_end - month_start + 1)
      )
    
    result %>% filter(ID == 1)
    
    # ID      start        end     perc month_start  month_end      pay TEST_MONTH TEST_DAYS      PAID
    # 1  1 2014-01-01 2014-03-05 23.73546  2014-01-01 2014-01-31 1949.884          1        31 462.81390
    # 2  1 2014-01-01 2014-03-05 23.73546  2014-02-01 2014-02-28 2014.691          1        28 478.19633
    # 3  1 2014-01-01 2014-03-05 23.73546  2014-03-01 2014-03-31 1933.150          1         5  74.00678
    # 4  1 2014-01-01 2014-03-05 23.73546  2014-04-01 2014-04-30 2127.622          0         0   0.00000
    # 5  1 2014-03-05 2014-04-12 31.83643  2014-01-01 2014-01-31 1949.884          0         0   0.00000
    # 6  1 2014-03-05 2014-04-12 31.83643  2014-02-01 2014-02-28 2014.691          0         0   0.00000
    # 7  1 2014-03-05 2014-04-12 31.83643  2014-03-01 2014-03-31 1933.150          1        27 536.03354
    # 8  1 2014-03-05 2014-04-12 31.83643  2014-04-01 2014-04-30 2127.622          1        12 270.94364
    

    【讨论】:

    • 非常感谢!!!是的,这行得通。我不会想出left_join。完全有道理。 :-)
    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2013-10-26
    • 1970-01-01
    相关资源
    最近更新 更多