2016-05-13 74 views
0

我是新来的R和需要从一个历史时期创建变量帮助。创建历史窗口变量R中

让我们假设,我的数据结构

User_ID Tran_date Fraud_ind 
A  1-Jan-15 1 
A  2-Jan-15 1 
A  3-Jan-15 0 
A  4-Jan-13 0 
A  5-Jan-10 1 

我需要创建使用滚动窗口的可变以下。意思是,我需要创建在过去365天内对应于User_Id A的欺诈率。在这种情况下,答案应该是

/(在最近365天的交易 数)

这是(在过去365天内欺诈交易的数量)

2/3 = 66.66%

请帮我计算一下R

+0

您需要添加数据集以其他方式帮助一个重复的例子,是非常困难的。看看'dput()'函数来帮助这个 –

+0

“last 365 days”是什么意思?你是否想从当前日期或某个指定日期找出差异?如果你想从现在的日期找到,那么我担心输出是错误的。 –

回答

0

你可以使用一个rollmean功能,只要确保你的数据是有序的,以及:

library(dplyr) 
library(zoo) 

TS_data<-read.csv("data.csv",stringsAsFactors = F) 

Roll.Mean <- TS_data %>% 
    filter(User_ID == "A") %>% 
    mutate(
    avg.365 = rollmean(x = Fraud_ind, 
          k = 3, 
          fill = NA) 
) 

>Roll.Mean 

    User_ID Tran_date Fraud_ind avg.365 
1  A 01-Jan-15   1  NA 
2  A 02-Jan-15   1 0.6666667 
3  A 03-Jan-15   0 0.3333333 
4  A 04-Jan-13   0 0.3333333 
5  A 05-Jan-10   1  NA 

显然,在你的情况,kk=365

+0

如果有一个额外的步骤添加缺失值(使用“Fraud_ind = 0”),此函数可以立即使用'k = 365' –

0

可能更容易为您的工作与简单的非滚动参数化聚合。下面是我在想什么:

fraudRate <- function(df,endDate,lookbackDays) { 
    endDate <- as.Date(endDate); 
    startDate <- endDate-lookbackDays+1L; 
    df <- subset(df,Tran_date>=startDate & Tran_date<=endDate); 
    aggregate(Fraud_ind~User_ID,df,function(x) sum(x)/length(x)); 
}; ## end fraudRate() 

您可以通过fraudRate()运行一个循环计算它的不同endDate/lookbackDays参数。


演示:

:在你的示例数据

## generate data 
set.seed(1L); 
NU <- 3L; ND <- 365L*2L; NT <- 15L; probFraud <- 1/3; 
df <- data.frame(
    User_ID=sample(LETTERS[1:3],NT,T), 
    Tran_date=sub('^0','',format(sort(sample(seq(as.Date('2014-01-01'),by=1L,len=ND),NT,T)),'%d-%b-%y')), 
    Fraud_ind=sample(c(1,0),NT,T,c(probFraud,1-probFraud)) 
); 

## clean up data 
df$Tran_date <- as.Date(df$Tran_date,'%d-%b-%y'); ## date column to R Date type 
df$Fraud_ind <- df$Fraud_ind==1; ## fraud column to R logical type 

df; 
## User_ID Tran_date Fraud_ind 
## 1  A 2014-01-10  FALSE 
## 2  B 2014-04-02  FALSE 
## 3  B 2014-06-04  FALSE 
## 4  C 2014-07-15  FALSE 
## 5  A 2014-09-06  TRUE 
## 6  C 2014-10-05  TRUE 
## 7  C 2014-10-07  TRUE 
## 8  B 2014-10-09  FALSE 
## 9  B 2014-12-30  TRUE 
## 10  A 2015-04-21  FALSE 
## 11  A 2015-06-08  TRUE 
## 12  A 2015-07-22  FALSE 
## 13  C 2015-09-27  TRUE 
## 14  B 2015-11-14  FALSE 
## 15  C 2015-12-26  FALSE 
fraudRate(df,'2015-06-01',365L); 
## User_ID Fraud_ind 
## 1  A 0.5000000 
## 2  B 0.3333333 
## 3  C 0.6666667 

演示

df <- data.frame(User_ID=c('A','A','A','A','A'),Tran_date=c('1-Jan-15','2-Jan-15','3-Jan-15','4-Jan-13','5-Jan-10'),Fraud_ind=c(1L,1L,0L,0L,1L),stringsAsFactors=F); 
df$Tran_date <- as.Date(df$Tran_date,'%d-%b-%y'); ## date column to R Date type 
df$Fraud_ind <- df$Fraud_ind==1; ## fraud column to R logical type 
df; 
## User_ID Tran_date Fraud_ind 
## 1  A 2015-01-01  TRUE 
## 2  A 2015-01-02  TRUE 
## 3  A 2015-01-03  FALSE 
## 4  A 2013-01-04  FALSE 
## 5  A 2010-01-05  TRUE 
fraudRate(df,max(df$Tran_date),365L); 
## User_ID Fraud_ind 
## 1  A 0.6666667 
0

类似的解决方案@bgoldst:

# create numerical julian date for each transaction 
dat$Tran_date <- as.Date(dat$Tran_date, "%d-%b-%y") 
dat$jday<-as.numeric(dat$Tran_date) 

# function to count number of frauds/total number of transactions in 365 days of x 
fraud_fun<-function(x){ 
    frauds<-sum(dat[((x - dat$jday) <=365) & ((x - dat$jday) >=0), "Fraud_ind"]) 
    total <- nrow(dat[((x - dat$jday) <=365) & ((x - dat$jday) >=0),]) 
    frauds/total 
} 


dat$fraud_365<-sapply(dat$jday, fraud_fun) 
    User_ID Tran_date Fraud_ind jday fraud_365 
1  A 2015-01-01   1 16436 1.0000000 
2  A 2015-01-02   1 16437 1.0000000 
3  A 2015-01-03   0 16438 0.6666667 
4  A 2013-01-04   0 15709 0.0000000 
5  A 2010-01-05   1 14614 1.0000000