2017-08-10 43 views
1

我对R相对比较陌生,对Shiny(字面上第一天)更新。操作textInput在R Shiny

我想用户输入多个短语,用逗号分隔,如female, aged, diabetes mellitus.我有一个数据帧,其中一个变量MH2包含文本字。我想输出一个数据帧,其中只包含所有输入短语所在的行。有时,用户可以输入只有一个短语,其他时间5

这是我ui.R

library(shiny) 
library(stringr) 

# load dataset 
load(file = "./data/all_cardiovascular_case_reports.Rdata") 

ui <- fluidPage(
    sidebarLayout(
    sidebarPanel(
     textInput(inputId = "phrases", 
       label = "Please enter all the MeSH terms that you would like to search, each separated by a comma:", 
       value = ""), 

     helpText("Example: female, aged, diabetes mellitus") 

    ), 
    mainPanel(DT::dataTableOutput("dataframe")) 
) 
) 

,这里是我的server.R

library(shiny) 

server <- function(input, output) 
{ 
    # where all the code will go 
    df <- reactive({ 

     # counts how many phrases there are 
     num_phrases <- str_count(input$phrases, pattern = ", ") + 1 

     a <- numeric(num_phrases) # initialize vector to hold all phrases 

     # create vector of all entered phrases 
     for (i in 1:num_phrases) 
     { 
     a[i] <- noquote(strsplit(input$phrases, ", ")[[i]][1]) 
     } 

     # make all phrases lowercase 
     a <- tolower(a) 

     # do exact case match so that each phrase is bound by "\\b" 
     a <- paste0("\\b", a, sep = "") 
     exact <- "\\b" 
     a <- paste0(a, exact, sep = "") 

     # subset dataframe over and over again until all phrases used 
     for (i in 1:num_phrases) 
     { 
     final <- final[grepl(pattern = a, x = final$MH2, ignore.case = TRUE), ] 
     } 

     return(final) 
    }) 

    output$dataframe <- DT::renderDataTable({df()}) 
} 

当我试图运行renderText({num_phrases})我即使我输入用逗号分隔的多个短语,也始终得到1。从那以后,每当我尝试输入多个短语时,我会遇到“错误:下标越界”。但是,当我输入用逗号分隔的单词与逗号和空格(输入“女性,年龄”而不是“女性,年龄”)时,​​该问题会消失,但我的数据框不能正确排列。它只能子集一个短语。

请指教。

谢谢。

回答

1

我认为你的Shiny逻辑看起来不错,但是对数据框进行子集化的功能有一些小问题。特别是:

a[i] <- noquote(strsplit(input$phrases, ", ")[[i]][1])

该指数[[i]]1是在错误的地方在这里,应该是[[1]][i]

final <- final[grepl(pattern = a, x = final$MH2, ignore.case = TRUE), ] 

不能匹配这样的多个模式,只一会的第一要素被使用,这也是R给出的警告。


示例工作代码

我已经改变了input$phrasesinp_phrases这里。如果这个脚本做了你想做的事情,我想你可以很容易地将它复制到你的反应中,进行必要的改变(例如,改回inp_phrases,并添加return(result)声明)。我也并不完全清楚,如果你想所有的模式,以一个行内的匹配,或返回的所有行都以任何格式相匹配,所以我加了他们两个,你可以取消你需要的:

library(stringr) 

# some example data 
inp_phrases = "ab, cd" 
final = data.frame(index = c(1,2,3,4),MH2 = c("ab cd ef","ab ef","cd ef ab","ef gx"),stringsAsFactors = F) 

# this could become just two lines: 
a <- sapply(strsplit(inp_phrases, ", ")[[1]], function(x) tolower(noquote(x))) 
a <- paste0("\\b", a, "\\b") 

# Two options here, uncomment the one you need. 
# Top one: match any pattern in a. Bottom: match all patterns in a 
# indices = grepl(pattern = paste(a,collapse="|"), x = final$MH2, ignore.case = TRUE) 
indices = colSums(do.call(rbind,lapply(a, function(x) grepl(pattern = x, x = final$MH2, ignore.case = TRUE))))==length(a) 

result <- final[indices,] 

返回:

index  MH2 
1  1 ab cd ef 
3  3 cd ef ab 

...与指数或第二版本(匹配所有)

index  MH2 
1  1 ab cd ef 
2  2 ab ef 
3  3 cd ef ab 

...与指数的第一个版本(匹配任意)

希望这会有所帮助!

+0

非常感谢!是的,这正是我正在寻找的。我使用了匹配所有短语的代码。再次感谢! – sweetmusicality

+0

没问题,很高兴我能帮忙! – Florian

+0

哎呀,谢谢你指出,修好了! – Florian