根据特定的逻辑计算条件累计值。

问题描述 投票:0回答:1

我是R的新手,有一个名为final的数据框作为主数据集,如下图所示。

dates_seq_ajay<-as.data.frame((seq(as.Date("2019/11/1"), by = "month", length.out = 6)))
ajay_emp_no <-1
ajay_ramped <-c(0,0,0,0,1,1)
ajay_loans <-c(1,22,17,25,21,23)
name<-"ajay"
data<-cbind(name,ajay_emp_no,dates_seq_ajay,ajay_ramped,ajay_loans)
colnames(data)<-c("name","emp_no","date","Flag","loans")


dates_seq_dv<-as.data.frame((seq(as.Date("2019/11/1"), by = "month", length.out = 4)))
dv_emp_no <-2
dv_flag <-c(0,0,0,0)
dv_loans <-c(2,15,42,1)
name<-"dv"
data1<-cbind(name,dv_emp_no,dates_seq_dv,dv_flag,dv_loans)
colnames(data1)<-c("name","emp_no","date","Flag","loans")



dates_seq_prince<-as.data.frame((seq(as.Date("2020/5/1"), by = "month", length.out = 5)))
prince_emp_no <-3
prince_flag <-c(0,0,0,1,1)
prince_loans <-c(16,31,28,32,23)
name<-"prince"
data2<-cbind(name,prince_emp_no,dates_seq_prince,prince_flag,prince_loans)
colnames(data2)<-c("name","emp_no","date","Flag","loans")

final<-rbind(data,data1,data2)

我有1000个员工在我的DF中,我想为每个员工找到月数、绩效和累计绩效,如果一个员工第一次遇到标志1,那么在下面的操作中按要求计算。

如果员工标志为0,没有标志1,则计算月份、绩效和累计绩效,直到我们有记录为止。

对于每个员工

月是他存在的月数。

绩效是指每月贷款占贷款总额的分数。

贷款总额是所有贷款的总和,直到找到旗子为止。第一次 如果标志总是为0,那么贷款总额就是所有贷款的总和。

累计业绩是指在遇到标志1之前,员工每一步的累计贷款总额。

输出如下图所示,只针对3名员工,但我需要为所有的1000名员工制定一个共同的逻辑。

enter image description here

r dplyr tidyverse tidyr lubridate
1个回答
2
投票

我们按'名称'分组,取'Flag'('tmp')的累计和建立一个临时列,得到 row_number() 月",创建 "绩效",将 "贷款 "除以 sum '贷款'的'tmp'根据'tmp'小于2的条件,'CumulativePerformance'根据'Performance'的累计和。 然后,我们根据'tmp'列的条件,将这些列中的行替换为NA,并将'tmp'

library(dplyr) #1.0.0
final %>%
    group_by(name) %>% 
    mutate(tmp = cumsum(Flag), 
           Month = row_number(), 
           Performance= loans/sum(loans[tmp <2]), 
           CumulativePerformance = cumsum(Performance)) %>%
    mutate(across(Month:CumulativePerformance, ~ replace(., tmp > 1, NA))) %>%
    ungroup %>%
    select(-tmp)
# A tibble: 15 x 8
#   name   emp_no date        Flag loans Month Performance CumulativePerformance
#   <chr>   <dbl> <date>     <dbl> <dbl> <int>       <dbl>                 <dbl>
# 1 ajay        1 2019-11-01     0     1     1      0.0116                0.0116
# 2 ajay        1 2019-12-01     0    22     2      0.256                 0.267 
# 3 ajay        1 2020-01-01     0    17     3      0.198                 0.465 
# 4 ajay        1 2020-02-01     0    25     4      0.291                 0.756 
# 5 ajay        1 2020-03-01     1    21     5      0.244                 1     
# 6 ajay        1 2020-04-01     1    23    NA     NA                    NA     
# 7 dv          2 2019-11-01     0     2     1      0.0333                0.0333
# 8 dv          2 2019-12-01     0    15     2      0.25                  0.283 
# 9 dv          2 2020-01-01     0    42     3      0.7                   0.983 
#10 dv          2 2020-02-01     0     1     4      0.0167                1     
#11 prince      3 2020-05-01     0    16     1      0.150                 0.150 
#12 prince      3 2020-06-01     0    31     2      0.290                 0.439 
#13 prince      3 2020-07-01     0    28     3      0.262                 0.701 
#14 prince      3 2020-08-01     1    32     4      0.299                 1.00  
#15 prince      3 2020-09-01     1    23    NA     NA                    NA     

如果我们有一个早期版本的 dplyr,使用 mutate_at 而不是 mutate(across

final %>%
        group_by(name) %>% 
        mutate(tmp = cumsum(Flag), 
               Month = row_number(), 
               Performance= loans/sum(loans[tmp <2]), 
               CumulativePerformance = cumsum(Performance)) %>%
        mutate_at(vars(Month:CumulativePerformance), ~ replace(., tmp > 1, NA)) %>%
        ungroup %>%
        select(-tmp)
© www.soinside.com 2019 - 2024. All rights reserved.