匹配字符串遍历多列
Matching strings loop over multiple columns
我有来自开放式调查的数据。我有评论 table 和代码 table。代码 table 是一组主题或字符串。
我想做什么:
检查代码 table 中相关列中是否存在单词/字符串在开放式评论中。在评论 table 中为特定主题添加一个新列,并用二进制 1 或 0 表示哪些记录已被标记。
代码 table 中有相当多的栏目,这些栏目是实时的并且不断变化,栏目顺序和栏目数量可能会发生变化。
我目前正在以一种相当复杂的方式执行此操作,我正在使用多行代码分别检查每一列,我认为可能有更好的方法来执行此操作。
我不知道如何让 lapply 与 stringi 函数一起工作。
非常感谢您的帮助。
这是一组示例代码,因此您可以看到我正在尝试做什么:
#Two tables codes and comments
#codes table
codes <- structure(
list(
Support = structure(
c(2L, 3L, NA),
.Label = c("",
"help", "questions"),
class = "factor"
),
Online = structure(
c(1L,
3L, 2L),
.Label = c("activities", "discussion board", "quiz"),
class = "factor"
),
Resources = structure(
c(3L, 2L, NA),
.Label = c("", "pdf",
"textbook"),
class = "factor"
)
),
row.names = c(NA,-3L),
class = "data.frame"
)
#comments table
comments <- structure(
list(
SurveyID = structure(
1:5,
.Label = c("ID_1", "ID_2",
"ID_3", "ID_4", "ID_5"),
class = "factor"
),
Open_comments = structure(
c(2L,
4L, 3L, 5L, 1L),
.Label = c(
"I could never get the pdf to download",
"I didn’t get the help I needed on time",
"my questions went unanswered",
"staying motivated to get through the textbook",
"there wasn’t enough engagement in the discussion board"
),
class = "factor"
)
),
class = "data.frame",
row.names = c(NA,-5L)
)
#check if any words from the columns in codes table match comments
#here I am looking for a match column by column but looking for a better way - lappy?
support = paste(codes$Support, collapse = "|")
supp_stringi = stri_detect_regex(comments$Open_comments, support)
supp_grepl = grepl(pattern = support, x = comments$Open_comments)
identical(supp_stringi, supp_grepl)
comments$Support = ifelse(supp_grepl == TRUE, 1, 0)
# What I would like to do is loop through all columns in codes rather than outlining the above code for each column in codes
这是一种使用 string::stri_detect_regex()
和 lapply()
的方法,根据 Support
、Online
或 Resources
向量在注释中,并将此数据与注释合并。
# build data structures from OP
resultsList <- lapply(1:ncol(codes),function(x){
y <- stri_detect_regex(comments$Open_comments,paste(codes[[x]],collapse = "|"))
ifelse(y == TRUE,1,0)
})
results <- as.data.frame(do.call(cbind,resultsList))
colnames(results) <- colnames(codes)
mergedData <- cbind(comments,results)
mergedData
...以及结果。
> mergedData
SurveyID Open_comments Support Online
1 ID_1 I didn’t get the help I needed on time 1 0
2 ID_2 staying motivated to get through the textbook 0 0
3 ID_3 my questions went unanswered 1 0
4 ID_4 there wasn’t enough engagement in the discussion board 0 1
5 ID_5 I could never get the pdf to download 0 0
Resources
1 0
2 1
3 0
4 0
5 1
>
一个使用 base R 的衬垫:
comments[names(codes)] <- lapply(codes, function(x)
+(grepl(paste0(na.omit(x), collapse = "|"), comments$Open_comments)))
comments
# SurveyID Open_comments Support Online Resources
#1 ID_1 I didn’t get the help I needed on time 1 0 0
#2 ID_2 staying motivated to get through the textbook 0 0 1
#3 ID_3 my questions went unanswered 1 0 0
#4 ID_4 there wasn’t enough engagement in the discussion board 0 1 0
#5 ID_5 I could never get the pdf to download 0 0 1
我有来自开放式调查的数据。我有评论 table 和代码 table。代码 table 是一组主题或字符串。
我想做什么: 检查代码 table 中相关列中是否存在单词/字符串在开放式评论中。在评论 table 中为特定主题添加一个新列,并用二进制 1 或 0 表示哪些记录已被标记。
代码 table 中有相当多的栏目,这些栏目是实时的并且不断变化,栏目顺序和栏目数量可能会发生变化。
我目前正在以一种相当复杂的方式执行此操作,我正在使用多行代码分别检查每一列,我认为可能有更好的方法来执行此操作。
我不知道如何让 lapply 与 stringi 函数一起工作。
非常感谢您的帮助。
这是一组示例代码,因此您可以看到我正在尝试做什么:
#Two tables codes and comments
#codes table
codes <- structure(
list(
Support = structure(
c(2L, 3L, NA),
.Label = c("",
"help", "questions"),
class = "factor"
),
Online = structure(
c(1L,
3L, 2L),
.Label = c("activities", "discussion board", "quiz"),
class = "factor"
),
Resources = structure(
c(3L, 2L, NA),
.Label = c("", "pdf",
"textbook"),
class = "factor"
)
),
row.names = c(NA,-3L),
class = "data.frame"
)
#comments table
comments <- structure(
list(
SurveyID = structure(
1:5,
.Label = c("ID_1", "ID_2",
"ID_3", "ID_4", "ID_5"),
class = "factor"
),
Open_comments = structure(
c(2L,
4L, 3L, 5L, 1L),
.Label = c(
"I could never get the pdf to download",
"I didn’t get the help I needed on time",
"my questions went unanswered",
"staying motivated to get through the textbook",
"there wasn’t enough engagement in the discussion board"
),
class = "factor"
)
),
class = "data.frame",
row.names = c(NA,-5L)
)
#check if any words from the columns in codes table match comments
#here I am looking for a match column by column but looking for a better way - lappy?
support = paste(codes$Support, collapse = "|")
supp_stringi = stri_detect_regex(comments$Open_comments, support)
supp_grepl = grepl(pattern = support, x = comments$Open_comments)
identical(supp_stringi, supp_grepl)
comments$Support = ifelse(supp_grepl == TRUE, 1, 0)
# What I would like to do is loop through all columns in codes rather than outlining the above code for each column in codes
这是一种使用 string::stri_detect_regex()
和 lapply()
的方法,根据 Support
、Online
或 Resources
向量在注释中,并将此数据与注释合并。
# build data structures from OP
resultsList <- lapply(1:ncol(codes),function(x){
y <- stri_detect_regex(comments$Open_comments,paste(codes[[x]],collapse = "|"))
ifelse(y == TRUE,1,0)
})
results <- as.data.frame(do.call(cbind,resultsList))
colnames(results) <- colnames(codes)
mergedData <- cbind(comments,results)
mergedData
...以及结果。
> mergedData
SurveyID Open_comments Support Online
1 ID_1 I didn’t get the help I needed on time 1 0
2 ID_2 staying motivated to get through the textbook 0 0
3 ID_3 my questions went unanswered 1 0
4 ID_4 there wasn’t enough engagement in the discussion board 0 1
5 ID_5 I could never get the pdf to download 0 0
Resources
1 0
2 1
3 0
4 0
5 1
>
一个使用 base R 的衬垫:
comments[names(codes)] <- lapply(codes, function(x)
+(grepl(paste0(na.omit(x), collapse = "|"), comments$Open_comments)))
comments
# SurveyID Open_comments Support Online Resources
#1 ID_1 I didn’t get the help I needed on time 1 0 0
#2 ID_2 staying motivated to get through the textbook 0 0 1
#3 ID_3 my questions went unanswered 1 0 0
#4 ID_4 there wasn’t enough engagement in the discussion board 0 1 0
#5 ID_5 I could never get the pdf to download 0 0 1