2016-06-20 42 views
0

我有以下數據集:在R中的grepl之後過濾數據集?

USERNAME API_TRACK_EVENT   TIME 
userA Viewed pic    1454941960 
userA Order/payment   1454941972 
userA Order/Changed Address 1454941976 
userB Viewed pic    1454941983 
userB Order/guestlogin  1454941986 
userB Order/Changed Address 1454941992 

我想只取前面的「訂單」,這意味着「訂單/支付」的用戶A和「訂單/ guestlogin」爲用戶B。

話雖如此,所有其他的無序事件應保持不變。

因此,輸出數據集將是:

USERNAME API_TRACK_EVENT   TIME 
userA Viewed pic    1454941960 
userA Order/payment   1454941972 
userB Viewed pic    1454941983 
userB Order/guestlogin  1454941986 

所以,我應該怎麼辦呢? [也可以使用dplyr。]

回答

3

下面是與基礎R選項:

0)順序根據USERNAME和TIME的數據:

df <- df[order(df$USERNAME, df$TIME),] 

a)檢查行是否包含命令信息:

idx <- grepl("Order", df$API_TRACK_EVENT, ignore.case = TRUE) 

b)中的子集由USERNAME的組

subset(df, ave(idx, USERNAME, FUN = cumsum) <= 1L | !idx) 

# USERNAME API_TRACK_EVENT  TIME 
#1 userA  Viewed_pic 1454941960 
#2 userA Order/payment 1454941972 
#4 userB  Viewed_pic 1454941983 
#5 userB Order/guestlogin 1454941986 

僅此子集的一階排和任何其他行(沒有訂單信息)。

+0

對不起,我錯過了行需要訂購acc的細節。到'時間',最早的一個應該存在於結果數據集中。感謝您對其他答案的評論,我已提醒有關錯誤:) – Dawny33

+0

@ Dawny33,我添加了一個步驟來訂購數據 –

+0

感謝您的詳細解答。 :) – Dawny33

2

我們可以使用slice/which.max/grep來篩選出dplyr中的行。在'USERNAME'分組後,我們得到一個邏輯索引號grepl,用which.max來包裝它,得到第一個TRUE值的數字索引,使用seq1:indexslice獲得序列以對行進行子集化。這種方法假定「Order」元素出現在每個「USERNAME」的末尾,如示例所示。

library(dplyr) 
df1 %>% 
    arrange(USERNAME, TIME) %>% 
    group_by(USERNAME) %>% 
    slice(seq(which.max(grepl("Order", API_TRACK_EVENT)))) 
# USERNAME API_TRACK_EVENT  TIME 
#  <chr>   <chr>  <int> 
#1 userA  Viewed pic 1454941960 
#2 userA Order/payment 1454941972 
#3 userB  Viewed pic 1454941983 
#4 userB Order/guestlogin 1454941986 

但是,如果「訂單」的元素是無序的,我們可以用duplicatedgrepl保持有沒有「秩序」或僅第一個「訂購」元素的任何元素的行。

df1 %>% 
    arrange(USERNAME, TIME) %>% 
    group_by(USERNAME) %>% 
    filter({idx = grepl("^Order", API_TRACK_EVENT); 
      !duplicated(idx)|!idx}) 

# USERNAME API_TRACK_EVENT  TIME 
#  <chr>   <chr>  <int> 
#1 userA  Viewed pic 1454941960 
#2 userA Order/payment 1454941972 
#3 userB  Viewed pic 1454941983 
#4 userB Order/guestlogin 1454941986 

注:與貢獻編輯從@docendodiscimus


或者使用第一種方法與data.table

library(data.table) 
setDT(df1)[df1[order(USERNAME, TIME), .I[seq(which.max(grepl("Order", 
         API_TRACK_EVENT)))], USERNAME]$V1] 
+0

可能解釋最後一行嗎? '(seq(which.max(grep(「Order」,API_TRACK_EVENT))))'< - This – Dawny33

+0

@akrun(+1)謝謝你的回答。如果需要根據時間進行排序,並希望採取「最早」的方法,可以做些什麼改變?對不起,錯過了qn的細節:) – Dawny33

+0

@docendodiscimus感謝您的評論。我忘了'{}' – akrun