检测字符串是否按特定顺序出现
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
我们可以分别得到Count
和CorrOrder
。为了得到 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
我想计算我的学生可以说出 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
我们可以分别得到Count
和CorrOrder
。为了得到 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