2016-05-13 79 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