Reputation: 6496
I'm struggling with a flexdashboard
as I can't find a way to pass a variable name to data.table
.
I've gone through How can one work fully generically in data.table in R with column names in variables and all referenced questions, also Use data.table within another function in R and many similar ones, trying get
, mget
, ..
, eval
to no avail (I've tried with = FALSE
and with = TRUE
too).
The reproducible example and what I've already tried is in the .Rmd
file that follows:
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(data.table)
library(ggplot2)
library(shiny)
```
```{r, include = FALSE}
a <- data.table(x = c(1, 1, 2, 3), y = c(1, 2, 3, 3), z = c(1, 2, 2, 3))
```
Column {.sidebar, data-width=75}
-----------------------------------------------------------------------
```{r}
selectInput("varname", label = "tell me the variable", choices = c("x", "y", "z"), selected = "z")
```
Column
-----------------------------------------------------------------------
### when in the "by", it works
```{r}
renderPlot({ggplot(a[, sum(x), by = c(input$varname)], aes(x = get(input$varname), y = V1))+geom_line()})
```
### varname
```{r}
renderPrint(input$varname)
```
### vector
```{r}
renderPrint(a[, get(input$varname)])
```
### Now this fails: with get (either with = FALSE or = TRUE)
```{r}
renderPlot({ggplot(a[, sum(get(input$varname)), by = z], aes(x = z, y = get(input$varname)))+geom_point()})
```
Column
--------------------
### with c
```{r}
renderPlot({ggplot(a[, sum(c(input$varname)), by = z, with = FALSE], aes(x = z, y = get(input$varname)))+geom_point()})
```
### With mget
```{r}
renderPlot({ggplot(a[, sum(mget(input$varname)), by = z, with = FALSE], aes(x = z, y = get(input$varname)))+geom_point()})
```
### with eval
```{r}
renderPlot({ggplot(a[, sum(eval(input$varname)), by = z], aes(x = z, y = get(input$varname)))+geom_point()})
```
### with ..
```{r}
renderPlot({ggplot(a[, sum(..input$varname), by = z], aes(x = z, y = get(input$varname)))+geom_point()})
```
How can I achieve the plot I'm attempting?
EDIT:
I'm getting
Error: invalid 'type' (character) of argument
with c
and eval
; Error: object 'z' not found
with .SD[[input$varname]]
Error: value for 'z' not found
for mget
Error: object '..input' not found
for ..
Error: onject 'y' not found
for get
Upvotes: 0
Views: 248
Reputation: 25208
A possible approach:
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(data.table)
library(ggplot2)
library(shiny)
```
```{r, include = FALSE}
a <- data.table(A=c(1, 1, 2, 3), B=c(1, 2, 3, 3), C=c(1, 2, 2, 3))
```
Column {.sidebar, data-width=75}
-----------------------------------------------------------------------
```{r}
selectInput("var_x", label="the x variable", choices=c("A", "B", "C"), selected="A")
selectInput("var_y", label="y variable to be summed", choices=c("A", "B", "C"), selected="C")
```
Column
-----------------------------------------------------------------------
### proposal
```{r}
renderPlot({
ggplot(a[, sum(get(input$var_y)), by=eval(input$var_x)], aes(x=get(input$var_x), y=V1)) +
geom_line()
})
```
Fix is basically to follow what is mentioned in the data.table error message:
Error: 'by' appears to evaluate to column names but isn't c() or key(). Use by=list(...) if you can. Otherwise, by=eval((input$var_x)) should work. This is for efficiency so data.table can detect which columns are needed
Upvotes: 1