Добавление нового вычисляемого столбца на основе даты ввода пользователем

#r #shiny

#r #блестящий

Вопрос:

Это снимок данных, которые у меня есть

 Date         price Industry  stock
29/10/2018   3      Airline   A
28/10/2018   4      Airline   A
27/10/2018   2      Airline   A
29/10/2018   5      Bank      B
29/10/2018   3      Food      C
28/10/2018   4      Bank      B
27/10/2018   2      Bank      B
27/10/2018   6      Food      C
  

У меня также есть цена, дата начала и окончания, введенные пользователем.

 dateRangeInput('dateRange',
      label = 'Date range input: yyyy-mm-dd',
      start = min(dailyprice$Date), end = max(dailyprice$Date))
  

Я отфильтровал набор данных в реактивную функцию и построил график зависимости даты от цены.
Теперь мне нужно построить график на основе нового вычисляемого столбца.
Следует добавить новый столбец с формулой = цена — цена на дату начала (введите $ DateRange[1]) для этой конкретной акции, т. е. цена на дату, введенную пользователем
Если пользователь выбрал 27/10/2018 в качестве даты начала, то вывод должен быть

 Date         price Industry  stock  NewCol
29/10/2018   3      Airline   A      1   (3-2)
28/10/2018   4      Airline   A      2    (4-2)
27/10/2018   2      Airline   A      0    (2-2)
29/10/2018   5      Bank      B      -1   (5-6)
29/10/2018   8      Food      C       2   (8-7)  
28/10/2018   7      Bank      B       1
27/10/2018   6      Bank      B       0
27/10/2018   6      Food      C       0
  

Как я могу выполнить это вычисление?

Я пробовал эти коды, но не получил желаемого результата:

   row <- subset(d , Date == input$dateRange[1] )
  d$newcol <- eval(parse(text="price - row"), d)
  sapply(d, function(d){d-row})
  

Комментарии:

1. Загляните в dplyr::mutate , data.table пакет или просто d$newcol <- d$price - row['price'] . Использование eval(parse( почти всегда действительно плохая идея. Похоже, здесь нет ничего особенного, поэтому вы должны иметь возможность использовать любую опцию, которая добавляет новую переменную в dataframe

Ответ №1:

Вот подход — не показывать график, но надеюсь, что это охватывает суть проблемы:

 library(shiny)
library(tidyverse)

df <- readr::read_table("
Date         price Industry  stock
29/10/2018   3      Airline   A
28/10/2018   4      Airline   A
27/10/2018   2      Airline   A
29/10/2018   5      Bank      B
29/10/2018   8      Food      C
28/10/2018   7      Bank      B
27/10/2018   6      Bank      B
27/10/2018   6      Food      C
")

df$Date <- format(lubridate::dmy(df$Date), '%Y-%m-%d')

ui <- fluidPage(
  dateRangeInput(
    'dateRange',
    label = 'Date range input: yyyy-mm-dd',
    start = min(df$Date), 
    end = max(df$Date)
  ),
  tableOutput("tbl")
)

server <- function(input, output, session) {
  df_new <- reactive({
    selected_date <- lubridate::ymd(input$dateRange[1])
    df %>%
      group_by(stock) %>%
      mutate(
        price_at_date = price[Date == selected_date],
        new_price = price - price_at_date
      )
  })
  output$tbl <- renderTable({
    df_new()
  })
}

shinyApp(ui = ui, server = server)
  

Блестящее приложение