2016-08-05 6 views
0

私はすでにthis question地図2つのデータフレーム

を尋ねた。しかし、今、私の現在の問題は、私はこのソリューションを使用するかを見つけ出すことができなかったことを少し異なります。私はデータからのデータは、データセット2前に発生した1を設定し、これが私のデータであるたいと思います:

# Dataset 1 (dts1) 

    UserID date Hour  Events  
    1 5 25/07/2016 02:31  8   
    2 5 30/07/2016 02:42  6  
    3 4 23/07/2016 07:52  9   
    4 14 24/07/2016 03:02  5   
    5 17 25/07/2016 09:12  10   
    6 4 22/07/2016 03:22  4 

# Dataset 2 (dts2) 

    UserID  date Hour  transactions  
1  5 25/07/2016 02:29  4   
2  4 24/07/2016 02:42  2  
3  5 25/07/2016 02:52  3   
4  6 24/07/2016 03:02  4   
5  6 25/07/2016 03:12  1   
6 14 26/07/2016 03:22  3 

をだから、私は、データセット1からこれらのデータセットを比較したいだけ追加しますつまり、データの最後のトランザクションの後に発生したイベントをカウントしないようにしたいと考えています。次のように理想的な出力は次のとおりです。上記の例で

#output 

    UserID Events  transaction 

    5   8   4,3 
    4   9,4  2 
    14   5   3 
    17   10  NA 

、私はそれが彼の最後のトランザクションの後に起こったので、私は、ユーザ5のイベント6を除去したことを確認しました。

+0

なぜこの質問をd​​ownvoteしましたか教えてください?私は最近ここで活動していて、あまりよく知られていません。 – MFR

+0

ダウンボートは私ではありませんでしたが、通常、あなたがやろうとしたこととあなたが立ち往生した場所を示すことは良い習慣です。 [良い質問をするにはどうすればいいですか?](http://stackoverflow.com/help/how-to-ask)を参照してください。 –

答えて

2

これは、以前の質問に対する@dimitris_psの回答です。彼が答えを選ぶなら、私は喜んで私のものを削除するでしょう。

この問題とあなたの前の問題の主な違いは、私たちが今、各特定UserIDため最後dts2トランザクションの前にあるすべてのdts1イベントをしたいということです。したがって、dts1イベント時刻が最後のdts2トランザクション時間より短い行のみ、group_byを最初にUserIDに、次にfilterにする必要があります。次に、summariseは、ユニークなEventstransactionsの両方であり、まだUserIDでグループ化できます。

コードは次のとおりです。

library(dplyr) 

## I will not use the lubridate package, instead I will convert the time 
## using as.POSIXct 
dts1$time <- as.POSIXct(paste(dts1$date, dts1$Hour), format="%d/%m/%Y %H:%M") 
dts2$time <- as.POSIXct(paste(dts2$date, dts2$Hour), format="%d/%m/%Y %H:%M") 

# first join the two data.frames by UserID. 
result <- left_join(dts1, dts2, by="UserID") %>% 

# all subsequent processing is grouped by the UserID because we 
# want to compare the last transaction time to the Event times 
# for each UserID. 
group_by(UserID) %>% 

# apply the filtering condition dts1 Event must be before last dts2 transaction. 
# Note that we keep rows for which there is no row in 
# dts2 for a UserID in dts1. This is the case for UserID=17. 
filter(is.na(time.y) | last(time.y) > time.x) %>% 

# summarise Events and transactions 
summarise(Events = toString(unique(Events)), transactions = toString(unique(transactions))) 

結果は以下のとおりです。

print(result) 
## A tibble: 4 x 3 
## UserID Events transactions 
## <int> <chr>  <chr> 
##1  4 9, 4   2 
##2  5  8   4, 3 
##3  14  5   3 
##4  17  10   NA 

は、この情報がお役に立てば幸いです。

+0

ありがとう、それは多くの助けになった – MFR

2

まず、時刻をPOSIXクラスに変換します。

dts1$time <- strptime(paste(dts1$date, dts1$Hour), format="%d/%m/%Y %H:%M") 
dts2$time <- strptime(paste(dts2$date, dts2$Hour), format="%d/%m/%Y %H:%M") 

次のステップは、transactions列を作ることです。最初にdts2を時間順(最新から早い順)にソートし、次にby()機能を使用してサブセットdtsUserIDに設定し、各サブセットから最初の行を取ります。 UserIDごとにを使用してtransactionsを検索します。

dts2 <- dts2[order(dts2$time, decreasing=TRUE), ] 
out <- do.call(rbind, by(dts2[,c("UserID","time")], dts2$UserID, head, 1)) 
out$transactions <- tapply(dts2$transactions, dts2$UserID, c) 

最後に、説明したルールを使用してEvents列を作成します。

out$Events <- sapply(1:nrow(out), function(i) { 
    User2 <- out$UserID[i] 
    time2 <- out$time[i] 
    rows <- which(dts1$UserID==User2 & dts1$time<time2) 
    if (length(rows)>0) {    
     dts1$Events[rows] 
    } else { 
     NA 
    } 
}) 

結果:ユーザ17はdts2ではないので、それはoutに表示されていないことを

> out 
    UserID    time transactions Events 
4  4 2016-07-24 02:42:00   2 9, 4 
5  5 2016-07-25 02:52:00   3, 4  8 
6  6 2016-07-25 03:12:00   1, 4  NA 
14  14 2016-07-26 03:22:00   3  5 

注意。