检测字符串是否按特定顺序出现

Detecting whether strings arise in a specific order

我想计算我的学生可以说出 5 个特定单词的次数,并且 subset/filter 学生的回答中单词的顺序是正确的。 正确顺序=绿色、黄色、橙色、红色、黑色。 所有数据均为小写且无标点:

#     Student responses
Id    Data$Colors
1     green yellow orange red black
2     yellow green orange red black
3     red violet pink black
4     purple green orange red black
5     blue pink yellow scarlet   

我的目标输出是:

#   Student responses
Id  Data$Colors                                Data$Count   Data$CorrOrder
1   green yellow orange red black              5            TRUE
2   yellow green orange red blacks             4            FALSE
3   red violet pink black                      2            TRUE
4   purple green orange red black              4            TRUE
5   blue pink yellow brown                     1            NA
6   green yellow orange red very red black     4*           TRUE

-1 分重复。 我已经能够通过这样做获得计数列

Data <- c("\bgreen\b", "\byellow\b", "\borange\b", "\bred\b", "\bblack\b")

Data$Count<- str_count(Data$Colors, paste(Data, collapse = '|'))

但是,这不会减去像 Id 6 这样重复正确的颜色。

有人知道我如何生成 Data$CorrOrder 吗?

使用tidyverse我们可以分别得到CountCorrOrder。为了得到 Count 我们首先在 space 上拆分 Colors 并为每种颜色创建 separate_rows 以便于比较值。然后我们计算总数 all_colors 中每个 Id 中有多少 unique Colors 并且因为我们想为每个重复值给出 -1,所以我们将其减去每组中 duplicated 个值的数量给了我们总分。

all_colors <- c("green", "yellow", "orange", "red", "black")
library(tidyverse)

df1 <- df %>%
      left_join(df %>%
                 separate_rows(Colors, sep = "\s+") %>%
                 group_by(Id) %>%
                 summarise(count = max(sum(all_colors %in% unique(Colors)) - 
                                   sum(duplicated(Colors)), 0)))

为了获得正确的顺序,我们再次将颜色分成不同的行,只保留 all_colors 中的颜色并删除重复项,并检查颜色出现的顺序是否总是增加并分配逻辑 TRUE /FALSE 相应的值。

df1 %>%
   left_join(df1 %>%
              separate_rows(Colors, sep = "\s+") %>%
              group_by(Id) %>%
              filter(Colors %in% all_colors & !duplicated(Colors)) %>%
              summarise(new = if (n() == 1) NA 
              else all(diff(na.omit(match(Colors, all_colors))) > 0)))

#  Id                                 Colors CorOrder Count
#1  1          green yellow orange red black     TRUE     5
#2  2         yellow green orange red blacks    FALSE     4
#3  3                  red violet pink black     TRUE     2
#4  4          purple green orange red black     TRUE     4
#5  5                 blue pink yellow brown       NA     1
#6  6 green yellow orange red very red black     TRUE     4

首先,如果您将这些值视为 ordered 因子,则可以使用 is.unsorted:

检查它们是否已排序,无需排序
colorder <- c("green", "yellow", "orange", "red", "black")

spl <- lapply(strsplit(dat$Colors, "\s+"), ordered, levels=colorder)
cnt <- sapply(spl, function(x) length(unique(na.omit(x))) - sum(tabulate(x) > 1) )
cnt
#[1] 5 4 2 4 1 4
out <- !sapply(spl, is.unsorted, na.rm=TRUE)
out[cnt == 1] <- NA
out
#[1]  TRUE FALSE  TRUE  TRUE    NA  TRUE