2015-11-17 4 views
1

может кто-нибудь помочь мне решить эту проблему с помощью R? Представьте, что каждый идентификатор считывает одно сообщение, которое будет записываться в данные. Являются следующие данные:Рассчитать среднее значение сообщений для новых пользователей в R?

> data 
    id  date 
1 1 2015-10-01 
2 2 2015-10-01 
3 2 2015-10-01 
4 3 2015-10-01 
5 4 2015-10-01 
6 4 2015-10-01 
7 5 2015-10-02 
8 1 2015-10-02 
9 3 2015-10-02 
10 4 2015-10-02 
11 6 2015-10-02 
12 6 2015-10-02 
13 7 2015-10-02 
14 7 2015-10-02 
15 1 2015-10-03 
16 8 2015-10-03 
17 8 2015-10-03 
18 7 2015-10-03 
19 3 2015-10-03 
20 9 2015-10-03 
21 9 2015-10-03 
22 1 2015-10-04 
23 2 2015-10-04 
24 10 2015-10-04 
25 11 2015-10-04 
26 11 2015-10-04 

Например: ID1 считывает одно сообщение в первый день, ID2 читает два сообщения на второй день, и так далее. Что мне нужно рассчитать - это среднее число сообщений для идентификаторов, которые являются новыми по сравнению с первым днем, такие как id5, id6 и id7 - это новые идентификаторы, начиная с 2015-10-2, общие новые сообщения для этих трех идентификаторов 5 сообщений, поэтому среднее число сообщений для новых пользователей составляет 5/3. Первый день 2015-10-1 средний - 6/4 (6 сообщений и 4 новых идентификатора). Надеюсь, что результат будет показан как один dataframe, который содержит переменную числа новых пользователей, а также количество сообщений для нового пользователя и среднее.

+1

Согласно вашим данным, 'id 1' и' id 2' читают 1 и 2 сообщения в тот же день (2015-10-01), соответственно. И в вашем примере это 'uid', а не' id'. –

ответ

0

Это подход dplyr. На каждую дату вычисляется количество новых пользователей и количество сообщений, которые эти пользователи читают.

dt = read.table(text= 
"uid  date 
1 1 2015-10-01 
2 2 2015-10-01 
3 2 2015-10-01 
4 3 2015-10-01 
5 4 2015-10-01 
6 4 2015-10-01 
7 5 2015-10-02 
8 1 2015-10-02 
9 3 2015-10-02 
10 4 2015-10-02 
11 6 2015-10-02 
12 6 2015-10-02 
13 7 2015-10-02 
14 7 2015-10-02 
15 1 2015-10-03 
16 8 2015-10-03 
17 8 2015-10-03 
18 7 2015-10-03 
19 3 2015-10-03 
20 9 2015-10-03 
21 9 2015-10-03 
22 1 2015-10-04 
23 2 2015-10-04 
24 10 2015-10-04 
25 11 2015-10-04 
26 11 2015-10-04", header=T) 

library(dplyr) 
library(lubridate) 

# save date as date object 
dt$date = ymd(dt$date) 


data.frame(date = unique(dt$date)) %>%   ## get unique dates in your initial dataset 
    group_by(date) %>%       ## for each date 
    do({new_ids = setdiff(unique(dt[dt$date == ymd(.$date),]$uid), ## get unique new user ids 
         unique(dt[dt$date < ymd(.$date),]$uid)) 
     N_new_ids = length(new_ids)         ## count those new user ids 
     N_msg = nrow(dt[dt$date == ymd(.$date) & dt$uid %in% new_ids,]) ## count number of messages the new users read 
     data.frame(N_new_ids, N_msg)}) %>%       ## create results 
    ungroup() %>% 
    mutate(Avg = N_msg/N_new_ids)         ## calculate average 


#   date N_new_ids N_msg  Avg 
#  (time)  (int) (int) (dbl) 
# 1 2015-10-01   4  6 1.500000 
# 2 2015-10-02   3  5 1.666667 
# 3 2015-10-03   2  4 2.000000 
# 4 2015-10-04   2  3 1.500000 
+1

Спасибо! Я проверяю, что он работает. Я слишком занят вчера. Есть ли у вас совет, чтобы помочь мне быстро изучить R? – fen

+0

Не совсем конкретный простой способ сделать это. Зависит от человека и сколько времени вы можете потратить в день. Просто начните использовать его много и экспериментируйте со своими (имитируемыми) наборами данных. Создайте набор данных и дайте задания для себя. Обработка данных (объединение, переформатирование, обновление переменных) и анализ данных в основном. – AntoniosK

+0

Да, я потрачу больше времени на изучение этого! Благодаря:) – fen

0

Возможно, вы можете использовать цикл «для», чтобы решить эту проблему, если вы не хотите вводить новые библиотеки.

1) Считать данные

x<-read.table(text= 
"uid  date 
1 1 2015-10-01 
2 2 2015-10-01 
3 2 2015-10-01 
4 3 2015-10-01 
5 4 2015-10-01 
6 4 2015-10-01 
7 5 2015-10-02 
8 1 2015-10-02 
9 3 2015-10-02 
10 4 2015-10-02 
11 6 2015-10-02 
12 6 2015-10-02 
13 7 2015-10-02 
14 7 2015-10-02 
15 1 2015-10-03 
16 8 2015-10-03 
17 8 2015-10-03 
18 7 2015-10-03 
19 3 2015-10-03 
20 9 2015-10-03 
21 9 2015-10-03 
22 1 2015-10-04 
23 2 2015-10-04 
24 10 2015-10-04 
25 11 2015-10-04 
26 11 2015-10-04", header=T) 

Вы должны знать дату начала, чтобы начать итерации с. Затем для каждой новой даты старые пользователи будут ничем иным, как пользователями, принадлежащими к более ранним датам.

Так что для итерации, имеющей новые даты, подмножество данных, чтобы удалить старых пользователей. См. Следующий код:

#Get the start date and find all the unique dates available 
start_date<-min(x$date) 
uniq_date<-unique(x$date) 

#Create variables which are required 
#In our case the new data frame would just need no of new users, messages and average messages. 
old_users<-numeric(0) 
new_users<-numeric(0) 
new_msgs<-numeric(0) 
avg_msg<-numeric(0) 

#Create the data frame with 0 rows and required columns 
new_data<-data.frame(Date=character(0),users=numeric(0),msgs=numeric(0),msg=numeric(0)) 

#order the x based on x, so that they start with the start date 
x<-x[order(x$date),] 

for(i in 1:length(uniq_date)) 
{ 
     #Subset the data for a date and excluding old_users 
     #For start_date, old_users is 'numeric(0)', i.e., no old users 

     temp_subset<-x[x$date %in% uniq_date[i] & !x$uid %in% old_users,] 

     #Calculating the required parameters for new data frame. 
     new_users=length(unique(temp_subset$uid)) 
     new_msgs=nrow(temp_subset) 
     avg_msg=new_msgs/new_users 

     #Include the results of a particular date to the new data frame 
     new_data<-rbind(new_data,data.frame(Date=uniq_date[i],users=new_users,msgs=new_msgs,avg=avg_msg)) 
     #When computation for a date is over, declare those ids as old_users 
     old_users=c(old_users,unique(temp_subset$uid)) 
} 

P.S. код может показаться длинным, но его очень просто понять.

Смежные вопросы