我一直在开发R Shiny中的动态数据框,根据许多用户输入(复选框,单选按钮,那种东西)进行过滤。对于其中一个选项,我试图根据不同字符串的向量过滤数据框,但在数据框中,它们存储为单个逗号分隔的字符串。
[,1] [,2]
[1,] "Sam" "C, Python, VB"
[2,] "Jess" "VB6, R"
[3,] "Mike" "Matlab, Java, Javascript"
[4,] "Sarah" "Python"
[5,] "Ahmad" "HTML, Ruby"
使用这个简化的例子,我有一组名称和他们知道的编程语言。我希望过滤的数据帧只包括那些知道Python或R的人。我的复选框将选择作为向量传递给
selections <- c("Python", "R")
使用选择向量过滤数据帧的结果应为
[,1] [,2]
[1,] "Sam" "C, Python, VB"
[2,] "Jess" "VB6, R"
[3,] "Sarah" "Python"
让过滤器工作是我的主要问题。
我一直在使用
将语言字符串转换为矢量strsplit(as.character(df[,2]), split=", ")
我可以过滤选择向量是否与数据帧完全匹配,但如果它只是部分相似则不能。
我正在尝试按照
的方式行事df %>%
filter(Languages %in% selections)
但无济于事。我也看过使用for循环,但那些让我感到不安的R,就像我在激怒矢量化的神。
我有什么遗失的吗?
修改1 在使用正则表达式的lmo建议之后,我设法让它工作。
将“C ++”作为选择之一导致了一些问题,所以我不得不用转义版本替换它。
selections <- replace(selections, selections=="C++", "C\\+\\+")
然后我将选择折叠为|用于正则表达式的分隔字符串
selections <- paste(selections, collapse = '|')
最后,我把它放入了lmo的建议
df <- df[grep(paste0("(^|, )(",
selections,
")(,|$)"),
df$Programming.Languages),]
如果我能弄清楚如何使它变得更紧凑(like in)
,我会将我用于反应性Shiny表达式的实际代码放入 编辑2
使用HTML snippit(尽管不运行)
# Filter the courses based on the language checkboxes
## A regular expression is used to filter
courseData <- reactive({
df <- courses
# The +'s in C++ cause a problem in the regex, so it is replaced with an escaped version
selections <- replace(input$languages, input$languages=="C++", "C\\+\\+")
selections = paste(selections, collapse = '|')
# This selects courses in the data frame who offer the selected languages
## grep returns the row numbers
df <- df[grep(paste0("(^|, )(",
selections,
")(,|$)"),
df$Programming.Languages.Taught),]
})
## The selections are made by selecting checkboxes, and the reactive expression is used later in the program
答案 0 :(得分:0)
我们需要unlist
从list
获得的strsplit
才能使其发挥作用。
df %>%
filter(Languages %in% unlist(selections))
答案 1 :(得分:0)
我认为这应该完成第二个变量中你要做的事情(包含R或python的行的子集)。假设您的数据是一个名为myMat的矩阵。然后尝试
myNewMat <- myMat[grep("(^|, )(R|Python)(,|$)", myMat[, 2]),]
这里,grep
将返回第二列中包含“R”或“Python”的元素的位置(行号),而不是选择像“Ruby”这样的子串。
请注意,如果myMat是data.frame,则相同的代码将起作用。