Как найти шаблон в определенном столбце в кадре данных? - PullRequest
0 голосов
/ 18 июня 2019

Я работаю над приложением Shiny и мне нужна помощь.

У меня есть датафрейм (загруженный из файла).Я хочу, чтобы пользователь мог извлекать строки, для которых определенное регулярное выражение появляется в определенном столбце этого фрейма данных.Позвольте мне перефразировать: я хочу, чтобы пользователь выбрал столбец из базы данных и поиска значений внутри этого конкретного столбца.

Позвольте мне показать вам пример.

  • пользователь выбирает столбец «Nutrient»

  • пользователь печатает мир «железо»

Результат: функциявозвращает все строки, в которых столбец «нутриент» содержит «железо».

С фиксированным столбцом это просто: вы просто используете grepl и извлекаете все строки, содержащие желаемое выражение.Но я не могу заставить его работать с определенной колонкой.Я посмотрел на бесчисленные вопросы и ответы, но ни один из них не принимает два ввода (скороговорка и столбец).

Это мой фрейм данных:

fileTable <- structure(list(
  omg = c("tomato", "domestic cat", "zebrafish", "giraffe", "common cougar", "fawn", "daim", "wild cat", "domestic cat", 
          "muren", "jaguar", "green turtle", "dave grohl", "zebra", "tortoise", "dinosaur", "apex mellifera"), 
  nutrient = c("iron", "iron", "zing", "nitrate", "manganese", "nitrogen", "bromure", "iron", "calcium", 
               "calcium", "iron", "sodium", "metal", "nitrates", "sodium", "calcium", "sodium"), 
  data3 = c(0.03, 0.02, 0.02, 0.09, 0.05, 0.04, 0.08, 0.05, 0.02, 0.07, 0.02, 0.01, 0.09, 0.12, 0.16, 0.08, 0.15)),
  row.names = c(NA, -17L), 
  class = "data.frame")

fileTable
#>               omg  nutrient data3
#> 1          tomato      iron  0.03
#> 2    domestic cat      iron  0.02
#> 3       zebrafish      zing  0.02
#> 4         giraffe   nitrate  0.09
#> 5   common cougar manganese  0.05
#> 6            fawn  nitrogen  0.04
#> 7            daim   bromure  0.08
#> 8        wild cat      iron  0.05
#> 9    domestic cat   calcium  0.02
#> 10          muren   calcium  0.07
#> 11         jaguar      iron  0.02
#> 12   green turtle    sodium  0.01
#> 13     dave grohl     metal  0.09
#> 14          zebra  nitrates  0.12
#> 15       tortoise    sodium  0.16
#> 16       dinosaur   calcium  0.08
#> 17 apex mellifera    sodium  0.15

Вот мой интерфейс:

#The user uses this input to select the column in which he wants to look
choices <- names(fileTable)
selectInput('column', 'From column:', choices , selected = choices[1])

#Here, he types the value he is looking for
filter <- textInput(inputId = "filter", label = "Filter" )

#And this button validates.
actionButton(inputId = "filterButton", label = "Filter")

А вот мой сервер:

 observeEvent(input$filterButton , {
    values <<- subset(theFile, grepl(input$filter, input$column, ignore.case = TRUE))
    print(values)
  })

Кажется, это не работает.Очевидно, grepl не может найти столбец с именем input$column в моем фрейме данных.Я заканчиваю этим:

OGM    Nutrient     data3     
<0 rows> (or 0-length row.names)

Спасибо за вашу помощь.Я застрял на этом некоторое время.Если вы хотите, чтобы я перефразировал, не стесняйтесь (не на английском языке здесь).

Ответы [ 3 ]

2 голосов
/ 18 июня 2019

Вы делаете несколько ошибок: 1. Не используйте <<-.Это не работает таким образом.Изменить данные внутри реактивных операторов.2. Чтобы создать фрейм данных на основе клика, всегда используйте eventReactive.В приложении вы найдете приложение, которое должно решить вашу проблему.

df <- data.frame(
    OGM = c("tomato", "domesticcat", "zebrafish", "giraffe", "common cougar", "fawn", "daim", "wild cat", "domestic cat", "muren", "jaguar", "green turtle", "dave grohl", "zebra", "tortoise", "dinosaur", "apex mellifera"),
    Nutrient = c("iron", "iron", "zing", "nitrate", "manganese", "nitrogen", "bromure", "iron", "calcium", "calcium", "iron", "sodium", "metal", "nitrates", "sodium", "calcium", "sodium"),
    data3 = c(0.03, 0.02, 0.02,  0.09, 0.05, 0.04, 0.08, 0.05, 0.02, 0.07, 0.02, 0.01, 0.09, 0.12, 0.16, 0.08, 0.15)
)


library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

   # Application title
   titlePanel("Match my data"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
        selectizeInput("column", "From column:", choices = colnames(df), selected = colnames(df)[1], multiple = FALSE),
        textInput(inputId = "filter", label = "Filter"),
        actionButton(inputId = "filterButton", label = "Filter")
      ),
      # Show a plot of the generated distribution
      mainPanel(
         tableOutput("table")
      )
   )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    filtereddf <- eventReactive(input$filterButton, {

        df[grepl(input$filter, df[[input$column]]), ]

            # filter(grepl(input$filter, input$column, ignore.case = TRUE))
    })

    output$table <- renderTable({

        if(input$filterButton == 0) {
            return(df)
        } else {
            return(filtereddf())
        }
    })
}


shinyApp(ui = ui, server = server)
1 голос
/ 18 июня 2019

Вы можете попробовать что-то вроде этого?

library(shiny)
data <- structure(list(OGM = c("tomato", "domestic cat", "zebrafish", 
                               "giraffe", "common cougar", "fawn", "daim", "wild cat", "domestic cat", 
                               "muren", "jaguar", "green turtle", "dave grohl", "zebra", "tortoise", 
                               "dinosaur", "apex mellifera"), Nutrient = c("iron", "iron", "zing", 
                                                                           "nitrate", "manganese", "nitrogen", "bromure", "iron", "calcium", 
                                                                           "calcium", "iron", "sodium", "metal", "nitrates", "sodium", "calcium", 
                                                                           "sodium"), data3 = c("0.03", "0.02", "0.02", "0.09", "0.05", 
                                                                                                "0.04", "0.08", "0.05", "0.02", "0.07", "0.02", "0.01", "0.09", 
                                                                                                "0.12", "0.16", "0.08", "0.15")), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                      -17L))
ui <- fluidPage(
    titlePanel("This app"),
    sidebarLayout(
        sidebarPanel(

         selectInput('column', 'From column:', choices = names(data)),
         uiOutput("COLUMN_VALUES")
        ),
    mainPanel(
        tableOutput("filtered_data"),
        h3("you also can try DT::datatable"),
        #DT::datatable(data)
        )
    ))

server <- function(input, output) {
 output$COLUMN_VALUES <- renderUI({
     selectInput("row", "From Row", choices = unique(sort(data[,input$column])), multiple = T)
 })

 output$filtered_data <- renderTable({
     req(input$row)
     data[grep(paste(input$row, collapse ="|"), data[,input$column]),]
     })
}
# Run the application 
shinyApp(ui = ui, server = server)
1 голос
/ 18 июня 2019

Поможет ли вам что-нибудь подобное?

df <- structure(list(
  omg = c("tomato", "domestic cat", "zebrafish", "giraffe", "common cougar", "fawn", "daim", "wild cat", "domestic cat", 
          "muren", "jaguar", "green turtle", "dave grohl", "zebra", "tortoise", "dinosaur", "apex mellifera"), 
  nutrient = c("iron", "iron", "zing", "nitrate", "manganese", "nitrogen", "bromure", "iron", "calcium", 
               "calcium", "iron", "sodium", "metal", "nitrates", "sodium", "calcium", "sodium"), 
  data3 = c(0.03, 0.02, 0.02, 0.09, 0.05, 0.04, 0.08, 0.05, 0.02, 0.07, 0.02, 0.01, 0.09, 0.12, 0.16, 0.08, 0.15)),
  row.names = c(NA, -17L), 
  class = "data.frame")


col_select <- "nut"
row_match <- "iron"

col_to_match <- grep(col_select, colnames(df))
rows_to_take <- df[, col_to_match] %in% row_match

df[rows_to_take, ]
#>             omg nutrient data3
#> 1        tomato     iron  0.03
#> 2  domestic cat     iron  0.02
#> 8      wild cat     iron  0.05
#> 11       jaguar     iron  0.02

Создано в 2019-06-18 пакетом представ. (v0.3.0)

...