如何在特定行之后查看n行

时间:2016-10-03 06:09:35

标签: r dplyr

我正在尝试跟踪用户操作,但我想看看他们在特定事件后做了什么。如何获得下一n行?

例如下面,我想知道用户在“获取蘑菇”之后正在做什么,看看他们是否正在吃它。我想为每个用户引用“获取蘑菇”,然后看看接下来的几行。

 User    Action
 Bob     Enter chapter 1
 Bob     Attack
 Bob     Jump
 Bob     Get mushroom
 Bob     Open inventory
 Bob     Eat mushroom 
 Bob     Close inventory
 Bob     Run
 Mary    Enter chapter 1
 Mary    Get mushroom
 Mary    Attack
 Mary    Jump
 Mary    Attack 
 Mary    Open inventory
 Mary    Close inventory 

我不确定在用户分组后如何处理此问题。如果我想要下面3行

,预期结果将如下所示
 User    Action
 Bob     Get mushroom # Action I want to find and the next 3 lines below it
 Bob     Open inventory
 Bob     Eat mushroom 
 Bob     Close inventory
 Mary    Get mushroom # Action I want to find and the next 3 lines below it
 Mary    Attack
 Mary    Jump
 Mary    Attack 

谢谢。

3 个答案:

答案 0 :(得分:2)

dplyrdata.table的两种选择:

library(dplyr)
df1 %>% 
  group_by(User) %>% 
  slice(rep(which(Action == 'Get-mushroom'), each=4) + 0:3)

library(data.table)
setDT(df1)[df1[, rep(.I[Action == 'Get-mushroom'], each=4) + 0:3, User]$V1]

两者都导致:

   User          Action
1:  Bob    Get-mushroom
2:  Bob  Open-inventory
3:  Bob    Eat-mushroom
4:  Bob Close-inventory
5: Mary    Get-mushroom
6: Mary          Attack
7: Mary            Jump
8: Mary          Attack

答案 1 :(得分:0)

首先使用Get mushroom

找出包含which一词的索引

您可以在每个索引上使用lapply,并使用seq获取接下来的3个索引。

args <- which(df$Action == "Get mushroom")
df[unlist(lapply(args, function(x) seq(x, x+3))), ]

#   User         Action
#4   Bob    Get mushroom
#5   Bob  Open inventory
#6   Bob    Eat mushroom
#7   Bob Close inventory
#10 Mary    Get mushroom
#11 Mary         Attack
#12 Mary           Jump
#13 Mary         Attack

或类似方法(@Sotos在评论中建议)

df[sapply(args, function(x) seq(x, x+3)), ]

sapply解决方案适用于数据框,而不适用于data.table,因为它不接受2列矩阵。

要使其适用于data.table,您可以使用c

取消列表
df[c(sapply(args, function(x) seq(x, x+3))), ]

答案 2 :(得分:0)

试试这个:

     df
   User         Action
1   Bob  Enterchapter1
2   Bob         Attack
3   Bob           Jump
4   Bob    Getmushroom
5   Bob  Openinventory
6   Bob    Eatmushroom
7   Bob Closeinventory
8   Bob            Run
9  Mary  Enterchapter1
10 Mary    Getmushroom
11 Mary         Attack
12 Mary           Jump
13 Mary         Attack
14 Mary  Openinventory
15 Mary Closeinventory

indices <- which(df$Action == 'Getmushroom')
n <- 3  
# ensure that x + n does not go beyond the #rows of df
do.call(rbind, lapply(indices, function(x)df[x:min(x+n, nrow(df)),]))


User         Action
4   Bob    Getmushroom
5   Bob  Openinventory
6   Bob    Eatmushroom
7   Bob Closeinventory
10 Mary    Getmushroom
11 Mary         Attack
12 Mary           Jump
13 Mary         Attack