2015-11-06 57 views
1

我是新来的R.这里是我的数据:如何计算每日保留率?

data 
    id  date 
1 1 2015/10/1 
2 2 2015/10/1 
3 3 2015/10/1 
4 4 2015/10/1 
5 5 2015/10/1 
6 1 2015/10/2 
7 3 2015/10/2 
8 4 2015/10/2 
9 6 2015/10/2 
10 7 2015/10/2 
11 1 2015/10/3 
12 7 2015/10/3 
13 3 2015/10/3 
14 9 2015/10/3 
15 1 2015/10/4 
16 10 2015/10/4 
17 11 2015/10/4 

我想计算的“身份证”的每一天的保留率。该id可能每天都有新的或重复的。我想把每天都当作最初的日期,并找到下一天的保留率。

到目前为止,我已经试过......

oct1<-data[which(data$date =="2015/10/1"),] 
oct2<-data[which(data$date == "2015/10/2"),] 
oct3<-data[which(data$date == "2015/10/3"),] 
oct4<-data[which(data$date == "2015/10/4"),] 

union_a1<-oct1$id[which(oct1$id%in%oct2$id)] 
union_a2<- oct1$id[which(oct1$id%in%oct3$id)] 
union_a3<- oct1$id[which(oct1$id%in%oct4$id)] 

per_a1=length(union_a1)/length(oct1$id) 
per_a2=length(union_a2)/length(oct1$id) 
per_a2=length(union_a3)/length(oct1$id) 

union_b1<-oct2$id[which(oct2$id%in%oct3$id)] 
union_b2<-oct2$id[which(oct2$id%in%oct4$id)] 

per_b1<-length(union_b1)/length(oct2$id) 
per_b2<- length(union_b2)/length(oct2$id) 

union_c1<-oct3$id[which(oct3$id%in%oct4$id)] 
per_c1<-length(union_c1)/length(oct3$id) 
per_a1 
# [1] 0.6 
per_a2 
# [1] 0.4 
per_a3 
# [1] 0.2 
per_b1 
# [1] 0.6 
per_b2 
# [1] 0.2 
per_c1 
# [1] 0.25 

谁能帮我写一个for循环来解决这个问题?我认为for循环很容易计算每一天。

回答

0

不是for循环的粉丝,所以我建议使用dplyr(数据操作)和lubridate(处理日期)的替代方法。 此过程使用分组和感兴趣的所有可能的日期组合来替换for循环。请注意,我正在考虑您在以下评论中提及的内容:您希望根据您在特定日期的新用户找到保留率。

library(dplyr) 
library(lubridate) 

data = read.table(text=" id  date 
        1 1 2015/10/1 
        2 2 2015/10/1 
        3 3 2015/10/1 
        4 4 2015/10/1 
        5 5 2015/10/1 
        6 1 2015/10/2 
        7 3 2015/10/2 
        8 4 2015/10/2 
        9 6 2015/10/2 
        10 7 2015/10/2 
        11 1 2015/10/3 
        12 7 2015/10/3 
        13 3 2015/10/3 
        14 9 2015/10/3 
        15 1 2015/10/4 
        16 10 2015/10/4 
        17 11 2015/10/4") 

## update your date column to date object 
data$date = ymd(data$date) 


expand.grid(date1 = unique(data$date),        ## create all combinations between dates 
      date2 = unique(data$date)) %>% 
    filter(date1 < date2) %>%          ## keep only cases where 2nd date is after 1st date 
    group_by(date1, date2) %>%          ## for each combination of dates 
    do({ids_1 = setdiff(unique(data[data$date == ymd(.$date1),]$id), ## get new ids in date1 (they showed up first time at this date) 
         unique(data[data$date < ymd(.$date1),]$id))   
    N_ids_1 = length(ids_1)           ## count how many ids you have 
    ids_2 = unique(data[data$date == ymd(.$date2),]$id)    ## get ids from date2 
    N_ids_2 = length(intersect(ids_2, ids_1))      ## count how many ids exist in previous dataset 
    data.frame(Prc = N_ids_2/N_ids_1)}) %>%       ## calculate the percentage   
    ungroup() 

#  date1  date2 Prc 
#  (time)  (time) (dbl) 
# 1 2015-10-01 2015-10-02 0.6 
# 2 2015-10-01 2015-10-03 0.4 
# 3 2015-10-01 2015-10-04 0.2 
# 4 2015-10-02 2015-10-03 0.5 
# 5 2015-10-02 2015-10-04 0.0 
# 6 2015-10-03 2015-10-04 0.0 
+0

非常感谢你〜dplyr的包真的很有用。其实我的时间数据格式为yyyy-mm-dd,我知道你首先将yyyy/mm/dd改为yyyy-mm-dd。我不知道如何改变这个问题。似乎do({dt1 = data [data $ date == ymd(。$ date1),]不适用于yyyy-mm-dd格式。 – fen

+0

是否可以执行'dput(data)'并且在这里发布输出,所以我可以看到你有什么格式? – AntoniosK

+0

我知道了,但是我的数据太长了,它只显示了十行,你能告诉我怎么能看到控制台的结果吗?保存结果? – fen