计算闪亮的反应数据帧内的eucledian距离

时间:2017-12-12 01:04:37

标签: r shiny

我正在尝试对dataframe中的被动shiny进行一些转换。我想在下面的代码中将函数euc.dist用于反应数据框bathy_new()

以下是可重现的例子:

library(shiny)
ui <- fluidRow(
  numericInput(inputId = "n", "Group ", value = 1), 
  plotOutput(outputId = "plot")
)

server <- function(input, output){
  bathy <- structure(list(`Corrected Time` = structure(c(
    1512040500, 1512040500,
    1512040501, 1512040502, 1512040502, 1512040503
  ), class = c(
    "POSIXct",
    "POSIXt"
  ), tzone = "UTC"), Longitude = c(
    -87.169858, -87.169858,
    -87.1698618, -87.1698652, -87.1698652, -87.16986785
  ), Latitude = c(
    33.7578743,
    33.7578743, 33.75788237, 33.75789018, 33.75789018, 33.75789717
  ), `Depth (m)` = c(
    3.95096, 3.82296, 3.63096, 3.57096, 3.48096,
    3.32096
  ), easting = c(
    484269.60819222, 484269.60819222, 484269.257751374,
    484268.944306767, 484268.944306767, 484268.700169299
  ), northing = c(
    3735323.04565401,
    3735323.04565401, 3735323.94098565, 3735324.80742908, 3735324.80742908,
    3735325.58284154
  ), diff = c(0, 0, 0, 0, 0, 0), group = c(
    1, 1,
    1, 2, 2, 2
  )), .Names = c(
    "Corrected Time", "Longitude", "Latitude",
    "Depth (m)", "easting", "northing", "diff", "group"
  ), row.names = c(
    NA,
    -6L
  ), class = c("tbl_df", "tbl", "data.frame"))



  euc.dist <- function(x1, y1, x2, y2){
    distance <- sqrt((x2-x1)^2 + (y2-y1)^2)
    return(distance)
  }
  # 
  bathy_new <- reactive({
    bathy %>% dplyr::filter(group == input$n)
  })

  test <- bathy_new() 

  dist <- NULL
  for (i in 1:nrow(test)){
    dist <- euc.dist(x1 = test[i, "easting"] %>% .$easting,
                     y1 = test[i, "northing"] %>% .$northing,
                     x2 = test[i+1, 'easting'] %>% .$easting,
                     y2 = test[i+1, 'northing'] %>% .$northing)
  }
  test$dist <- dist

  output$plot <- renderPlot(
    qplot(cumsum(test$dist), bathy_new()$`Depth (m)`)
  )
}

shinyApp(ui, server)

这里的数据与原始数据相比是非常小的数据。但目标是找到每组中各点之间的eucledian距离。在这个小数据集中,我有两组; 1和2.

我一直收到以下错误

Error in .getReactiveEnvironment()$currentContext() : Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

我可以在闪亮之外运行此代码,但不确定如何处理反应数据。

这是存在错误的代码块:

test <- bathy_new() 

      dist <- NULL
      for (i in 1:nrow(test)){
        dist <- euc.dist(x1 = test[i, "easting"] %>% .$easting,
                         y1 = test[i, "northing"] %>% .$northing,
                         x2 = test[i+1, 'easting'] %>% .$easting,
                         y2 = test[i+1, 'northing'] %>% .$northing)
      }
      test$dist <- dist

最后,我想绘制累积距离cum(dist)和深度Depth (m)

1 个答案:

答案 0 :(得分:2)

您收到该错误的原因是您实际上尝试将reactive分配给变量test。这只能在反应性表达或观察者内部完成。

因此,您需要做的是将该代码置于反应式表达式中,例如renderPlot

  output$plot <- renderPlot({
    test <- bathy_new() 

    dist <- NULL
    for (i in 1:(nrow(test) - 1)){
      dist <- euc.dist(x1 = test[i, "easting"] %>% .$easting,
                       y1 = test[i, "northing"] %>% .$northing,
                       x2 = test[i+1, 'easting'] %>% .$easting,
                       y2 = test[i+1, 'northing'] %>% .$northing)
    }

    test$dist <- dist
    qplot(cumsum(test$dist), bathy_new()$`Depth (m)`)
  })

这应该摆脱错误,但我认为你的for循环也可能有问题。您遍历1:nrow(test),但在循环内使用i+1进行计算。因为这将是NA,因此你的情节不会显示任何东西。

我修改了你的循环以迭代1:(nrow(test) - 1)以获得有效的结果。

我还想指出Shiny的工作方式。 Shiny在服务器函数之外运行代码每个R进程一次,然后在服务器函数每个连接一次内运行代码。然后,每当他们的依赖关系发生变化时,就会出现的反应。

有关更多帮助,请参阅this topic

因此,最好在server函数之外定义数据和函数,因为它们只需要运行一次。如果它们位于server函数内,则每次新用户连接到应用程序时都会运行它们,但它效率不高。

完整代码

library(shiny)
library(magrittr)
library(ggplot2)

bathy <- structure(list(`Corrected Time` = structure(c(
  1512040500, 1512040500,
  1512040501, 1512040502, 1512040502, 1512040503
), class = c(
  "POSIXct",
  "POSIXt"
), tzone = "UTC"), Longitude = c(
  -87.169858, -87.169858,
  -87.1698618, -87.1698652, -87.1698652, -87.16986785
), Latitude = c(
  33.7578743,
  33.7578743, 33.75788237, 33.75789018, 33.75789018, 33.75789717
), `Depth (m)` = c(
  3.95096, 3.82296, 3.63096, 3.57096, 3.48096,
  3.32096
), easting = c(
  484269.60819222, 484269.60819222, 484269.257751374,
  484268.944306767, 484268.944306767, 484268.700169299
), northing = c(
  3735323.04565401,
  3735323.04565401, 3735323.94098565, 3735324.80742908, 3735324.80742908,
  3735325.58284154
), diff = c(0, 0, 0, 0, 0, 0), group = c(
  1, 1,
  1, 2, 2, 2
)), .Names = c(
  "Corrected Time", "Longitude", "Latitude",
  "Depth (m)", "easting", "northing", "diff", "group"
), row.names = c(
  NA,
  -6L
), class = c("tbl_df", "tbl", "data.frame"))

euc.dist <- function(x1, y1, x2, y2){
  distance <- sqrt((x2-x1)^2 + (y2-y1)^2)
  return(distance)
}

ui <- fluidRow(
  numericInput(inputId = "n", "Group ", value = 1), 
  plotOutput(outputId = "plot")
)

server <- function(input, output){
  bathy_new <- reactive({
    bathy %>% dplyr::filter(group == input$n)
  })

  output$plot <- renderPlot({
    test <- bathy_new() 

    dist <- NULL
    for (i in 1:(nrow(test) - 1)){
      dist <- euc.dist(x1 = test[i, "easting"] %>% .$easting,
                       y1 = test[i, "northing"] %>% .$northing,
                       x2 = test[i+1, 'easting'] %>% .$easting,
                       y2 = test[i+1, 'northing'] %>% .$northing)
    }

    test$dist <- dist
    qplot(cumsum(test$dist), bathy_new()$`Depth (m)`)
  })
}

shinyApp(ui, server)