Say, biz iris
veri kümesi var ve bunun üzerine bazı subsetting yapmak istiyorum.
iris$Species
# We can also use `with` for that
with(iris, Species)
# We are interested in more complicated subsetting though. Want to have all rows
# with 'setosa'
with(iris, Species %in% 'setosa')
iris[with(iris, Species %in% 'setosa'), ]
# Now 'setosa' with some more condition
iris[with(iris, Species %in% 'setosa' & Sepal.Length > 5.3), ]
# That works perfectly. There is, however, an another way doing the exact thing in r.
# We can input the subsetting condition as a character string, then change it to
# the `expression` and `eval`uate it.
cond_str <- paste0("with(iris, Species %in% 'setosa' & Sepal.Length > 5.3)")
cond_str
# which is the same as
cond_str <- paste0("with(iris, ", "Species %in% ", "'", "setosa", "'", " & ",
"Sepal.Length > ", "5.3", ")")
cond_str
# This second approach will prove very powerful since we will replace "setosa"
# with, say, `input$species` later on.
cond <- parse(text = cond_str)
cond
eval(cond)
iris[eval(cond), ] # √
input$species
bir vektör olabileceğinden, biraz daha karışık alacak ve sonuç olarak biz çıktı olarak birden karakter dizeleri alabilirsiniz. Örneğin :
Şimdi
Spec <- c("setosa", "virginica") # ~ input$species
paste0("with(iris, Species %in% ", Spec, ")")
# We want only one character string! So, we'll have to collapse the vector Spec
paste0("with(iris, Species %in% ",
paste0(Spec, collapse = " "), ")")
# This is still not what we wanted. We have to wrap the entries into "c()"
# and add quote marks. So, it's going to be pretty technical:
paste0("with(iris, Species %in% ",
"c(", paste0("'", Spec, collapse = "',"), "'))")
# Now, this is what we wanted :) Let's check it
check <- eval(parse(text = paste0("with(iris, Species %in% ",
"c(", paste0("'", Spec, collapse = "',"), "'))")))
iris[check, ] # √
, en parlak uygulamasına geçelim. baseball
veri setini nerede bulabileceğimi bilmediğimden, diamonds
veri kümesini ggplot2
paketinden kullanacağım ve dplyr
kullanamayacağım.
Uygulamanızı değiştirdim - değişkenlerin isimlerini değiştirdim ve daha sonra, alt dizgi için yukarıda açıkladığım numarayı kullandım. Örneğinizi probleminize uymanız kolay olmalı. Eğer filter` `koşulları arasına virgül kullanırsanız
library(shiny)
library(DT)
# data("diamonds") don't know where I can find this dataset, hence I'll use
# diamond dataset
library(ggplot2) # for diamonds dataset
cut <- unique(as.character(diamonds$cut)) # or just levels(diamonds$cut)
color <- unique(as.character(diamonds$color))
clarity <- unique(as.character(diamonds$clarity))
runApp(list(ui = fluidPage(
titlePanel("Summary"),
sidebarLayout(
sidebarPanel(
# changed names of inputs
selectInput("cut", label = "Cut", choices = cut, selected = NULL, multiple = T),
selectInput("filter_join1", label = "", choices = c("OR","AND")),
selectInput("color", label = "Color", choices = color, selected = NULL, multiple = T),
selectInput("filter_join2", label = "", choices = c("OR","AND")),
selectInput("clarity", label = "Clarity", choices = clarity, selected = NULL, multiple = T)
),
mainPanel(
DT::dataTableOutput("table")
)
)
),
server = function(input, output, session) {
WorkingDataset <- reactive({
req(input$cut, input$color, input$clarity)
# show table only if all three inputs are available
# depending on filter_join inputs return "OR" or "AND"
join1 <- ifelse(test = input$filter_join1 == "OR", yes = "| ", no = "& ")
join2 <- ifelse(test = input$filter_join2 == "OR", yes = "| ", no = "& ")
# You could do this differently: just set choices = c("OR" = "|", "AND" = "&"))
# in the selectInput widget.
# Similar as in the example above with the iris dataset.
cond_str <- paste0(
"with(diamonds, ",
paste0("cut %in% ", "c(", paste0("'", input$cut, collapse = "',"), "')", colapse = " "),
join1,
paste0("color %in% ", "c(", paste0("'", input$color, collapse = "',"), "')", colapse = " "),
join2,
paste0("clarity %in% ", "c(", paste0("'", input$clarity, collapse = "',"), "')", colapse = " "),
")")
print(cond_str) # print the result to the console
cond <- parse(text = cond_str)
df <- as.data.frame(diamonds)[eval(cond), ]
df
})
output$table <- DT::renderDataTable({ WorkingDataset() })
})
)
, bu' & 'gibi çalışır. Bunun yerine '|' kullanmak için, virgülleri '|' ile değiştirmeniz gerekecektir. Bunu yapmanın en basit yolu (muhtemelen yine de oldukça titiz olsa da), bir sürü “if” ifadesidir. 'substitute' daha özlü olabilir, ancak dikkate değer ölçüde daha titiz olabilir. – alistaire
Merhaba Alistaire, mesajınız için teşekkürler. Kullanıcının filtreler arasında AND/OR'ye katılmasını seçmesini isterdim. Örneğin örnek kullanıcı aşağıdakileri yapabilmelidir: YIL VEYA Ekip VE Stint. veya diğer olası kombinasyonlar –
biliyorum. Açıkça kolay etkileşimli; Programatik olarak sadece bir ağrı. Yukarıdaki yorumum bazı başlangıç noktaları. – alistaire