R dplyr数据争论/重建挑战

时间:2018-02-15 17:41:53

标签: r dplyr tidyr

我试图记录持续时间超过或等于30秒的搜索会话。按时间和ID排列数据集后,数据集大致如下所示:

 ID  Action   Checkin
 a   search    NA
 a   visit     NA
 a   visit     NA
 a   checkin   10
 a   checkin   20
 a   checkin   30
 a   checkin   40
 a   checkin   50
 b   search    NA
 b   search    NA
 b   search    NA
 c   search    NA
 c   search    NA
 d   search    NA
 d   search    NA
 d   visit     NA
 d   checkin   10
 d   checkin   20
 e   search    NA
 e   visit     NA
 e   checkin   10
 e   checkin   20
 e   checkin   30

从上面的结构中,我希望生成一个按ID记录搜索次数的表格,对于每个不遵循访问次数或登记时间少于30秒的搜索,Check30将为F.那些随后访问并且签到时间超过30秒的搜索,check30将是T.我试图按max(Checkin)group_by(ID)进行过滤,但我无法获得Check30按行动报告search ...

你可以参考这篇文章: dplyr table reconstructing/data wrangling 这显示了我第一次尝试识别真实与虚假搜索,但现在我对反映签到持续时间> = 30感兴趣。

非常感谢帮助!

瞄准表格如下:

ID  Action   Check30
 a   search    T
 b   search    F
 b   search    F
 b   search    F
 c   search    F
 c   search    F
 d   search    F
 d   search    F
 e   search    T

致kgolyaev:

我修改了您的代码以适应原始数据集(https://github.com/wikimedia-research/Discovery-Hiring-Analyst-2016/blob/master/events_log.csv.gz) 在通过session_id离开加入之后,我得到了237953个obs,但我相信obs应该与seaches匹配,即136234 obs。

# pick all searches
searches <-  eventLog %>% 
filter(action == 'searchResultPage') %>% 
dplyr :: select(-checkin)

# pick all visits

visits <- eventLog %>% 
filter(action == 'visitPage') %>% 
dplyr :: select(-action)

# do a left join and create variable of interest

searchesAndVisits <- searches %>% 
left_join(visits, by = 'session_id', suffix = c("_search", "_visit")) %>% 
mutate( check30 = "FALSE", condition = ((checkin >= 30) & timestamp_search < 
timestamp_visit), check30=ifelse(condition, "TRUE", check30)) 

1 个答案:

答案 0 :(得分:1)

我创建了一个更小的示例,其中包含额外的时间列。希望这可以帮助。这使用包dplyr。我添加了一个ID,在搜索之前访问发生,以说明此代码也处理这种情况。

library('dplyr')
df <- readr::read_csv("ID,Action,Checkin,time
a,search,NA,1
a,visit,NA,2
b,search,NA,1
c,search,NA,1
c,visit,30,2
c,checkin,40,3
d,visit,30,1
d,search,NA,2")
df
# A tibble: 8 x 4
ID  Action Checkin  time
<chr>   <chr>   <int> <int>
1     a  search      NA     1
2     a   visit      NA     2
3     b  search      NA     1
4     c  search      NA     1
5     c   visit      30     2
6     c checkin      40     3
7     d   visit      30     1
8     d  search      NA     2    

分为搜索和访问:

# pick all searches
searches <- df %>% 
  filter(Action == 'search') %>% 
  select(-Checkin)
# pick all visits
visits <- df %>% 
  filter(Action == 'visit') %>% 
  select(-Action)

现在加入数据并将它们按到需要的形状。

# do a left join and create variable of interest
searchesAndVisits <- searches %>% 
  left_join(visits, by = 'ID', suffix = c("_search", "_visit")) %>% 
mutate(
    Check30 = "F"
    , condition = ( (Checkin >= 30) & !is.na(Checkin) # checkin at least 30 sec
                    & time_search < time_visit) # checkin after search 
    , Check30 = ifelse(condition,  "T", Check30)
  ) %>% 
  select(ID, Action, Check30)
searchesAndVisits
# A tibble: 4 x 3
ID Action Check30
<chr>  <chr>   <chr>
1     a search       F
2     b search       F
3     c search       T
4     d search       F

<强>更新

此策略会在每对“搜索”的最终数据中创建一行。并且&#39;访问&#39;每个身份证。请考虑以下示例。

df2 <- readr::read_csv("ID,Action,Checkin,time
a,search,NA,1
a,visit,30,2
a,search,NA,3
a,visit,40,4")
df2
# A tibble: 4 × 4
     ID Action Checkin  time
  <chr>  <chr>   <int> <int>
1     a search      NA     1
2     a  visit      30     2
3     a search      NA     3
4     a  visit      40     4    

在这里,我为同一个ID创建了两次搜索和两次访问。如果您运行我之前编写的相同代码并使其返回另外两个变量time_searchtime_visit,您将获得此输出:

searchesAndVisits
# A tibble: 4 × 5
     ID Action Check30 time_search time_visit
  <chr>  <chr>   <chr>       <int>      <int>
1     a search       T           1          2
2     a search       T           1          4
3     a search       F           3          2
4     a search       T           3          4

您现在有四行。两次搜索中的每一次都与两次访问中的每次访问配对。第一行是在时间1搜索,在时间2访问,第二行是在时间1搜索,在时间4访问。第三行是在时间3搜索,在时间2访问。最后一行是在时间3搜索与时间4的访问配对。

您很可能会删除第三行,并说如果在搜索之前发生访问,则将访问与搜索配对是不合理的。但是你想对第2行做什么呢?它正式满足您的要求:&#34;访问后搜索,签到时间至少30秒&#34;。这是额外行的来源,您需要决定如何处理它们。