如何根据给定每个动作的排名来检查一组动作的顺序?

时间:2019-03-27 22:41:03

标签: r

我有这个数据框。

user    action    date        rank
AAA     jump      2018-01-01  1
AAA     climb     2018-01-02  2
AAA     leap      2018-01-03  3
BBB     jump      2018-01-01  1
BBB     climb     2018-01-03  2
BBB     leap      2018-01-05  3
BBB     gallop    2018-01-08  4
CCC     leap      2018-01-01  1
CCC     climb     2018-01-02  2
CCC     gallop    2018-01-04  3

执行操作并根据日期按升序为每个用户添加排名。

我想找到以错误顺序执行操作的所有用户。顺序应为jump -> climb -> leap -> gallop

输出将为CCC,因为该用户确实在爬升之前跳了起来。

user   
CCC

您如何引用特定行?我正在使用dplyr,可以按每个用户将其分组,并使用row_number()添加每个用户的排名,但是我不知道如何制定规则来检查操作是否在正确的顺序。

注意-我意识到这还不清楚。并非每个用户都执行所有操作,但是顺序仍然很重要。

这是我到目前为止的工作

badData <- NULL
for (i in df$user){
  filtered <- filter(df, user == i)

  first <- ifelse(filtered[filtered$action == "jump",]$rank > 1, TRUE, FALSE)
  second <- ifelse(filtered[filtered$action == "climb",]$rank < filtered[filtered$action == "jump",]$rank, TRUE, FALSE)
  #and so on for the rest of the rules

  if(first + second > 0) badData <- c(badData, i)   
}

2 个答案:

答案 0 :(得分:2)

如果使action为因数并使用levels参数设置顺序,则可以按用户分组,然后使用is.unsorted测试操作是否未排序:

library(dplyr)

df %>%
  mutate(action = factor(action, levels = c("jump", "climb", "leap", "gallop"))) %>%
  group_by(user) %>%
  filter(is.unsorted(action)) %>%
  pull(user) %>%
  unique

[1] "CCC"

答案 1 :(得分:1)

这里是一个小例子,您可以实现此目的。 首先,您创建一个包含正确顺序的参考数据框(refdata)。 然后,您可以轻松使用tidyverse软件包:

mydata <- tibble(id = rep(c("aaa", "bbb", "ccc"), each = 4), action = letters[c(1:4, 1,2 ,4, 3, 4,1,2,3)],
       date = rep(1:3, 4)) 

refdata <- tibble(action = letters[1:4], right_order = 1:4)


mydata %>% left_join(refdata, by = "action") %>% group_by(id) %>% 
  summarise(test = identical(right_order, sort(right_order)))