0

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
2
  • what is going wrong w your current approach? Commented Jul 24, 2019 at 2:02
  • @MichaelChirico please see my edit Commented Jul 24, 2019 at 2:30

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.