使用逗号分隔列表进行过滤

时间:2016-07-11 14:50:11

标签: r dataframe filter tags

我一直在开发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

2 个答案:

答案 0 :(得分:0)

我们需要unlistlist获得的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,则相同的代码将起作用。