Shiny应用含data.table函数报错:unused argument (unit="hours")
问题解决:Shiny应用中
round()函数报错"unused argument (unit = 'hours')" 问题背景
有如下R数据框:
df <- data.frame( Timestamp =as.POSIXct(c(1689769414, 1689769426, 1689769438, 1689769450, 1689769462, 1689769474, 1689769486, 1689769499, 1689769511, 1689769523, 1689769534, 1689769547, 1689769559, 1689769570, 1689769583, 1689769595, 1689769607, 1689769618, 1689769630, 1689769642, 1689769654, 1689769666, 1689769678, 1689769690, 1689769703, 1689769714, 1689769726, 1689769739, 1689769750, 1689769763, 1689769774, 1689769786, 1689769799, 1689769810, 1689769823, 1689769835, 1689769847, 1689769860, 1689769871, 1689769884, 1689769895, 1689769907, 1689769919, 1689769931, 1689769944, 1689769956, 1689769968, 1689769982, 1689769995, 1689770021, 1689770035, 1689770047, 1689770059, 1689770072, 1689770083, 1689770096, 1689770107, 1689770119, 1689770132, 1689770143, 1689770155, 1689770168, 1689770181, 1689770197, 1689770208, 1689770221, 1689770233, 1689770246, 1689770257, 1689770270, 1689770282, 1689770293, 1689770306, 1689770318, 1689770329, 1689770342, 1689770354, 1689770384, 1689770395, 1689770407, 1689770420, 1689770432, 1689770444, 1689770456, 1689770469, 1689770482, 1689770493, 1689770505, 1689770517, 1689770530, 1689770542, 1689770555, 1689770568, 1689770579, 1689770591, 1689770603, 1689770615, 1689770628, 1689770640, 1689770652 )), Heat_Capacity = c( 5.5, 6, 6.5, 7, 7.5, 7, 6.5, 6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, 0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 6.96, 6.46, 5.96, 5.46, 4.96, 4.46, 3.96, 3.46, 2.96, 2.46, 1.92, 1.42, 0.83, 0.29, 0.79, 1.33, 1.88, 2.38, 2.88, 3.38, 3.88, 4.38, 4.88, 5.38, 5.88, 6.38, 6.92, 7.42, 6.92, 6.42, 5.92, 5.38, 4.88, 4.38, 3.88, 3.38, 2.88, 2.38, 1.88, 1.38, 0.88, 0.38, 0.88, 1.38, 1.88, 2.42, 2.92, 3.42, 3.92, 4.46, 4.96, 5.46, 5.96, 6.46, 6.96, 7.46, 6.96, 6.46, 5.96, 5.46, 4.96, 4.46, 3.96, 3.46, 2.96 ) )
基于该数据开发的Shiny应用如下:
library(shiny) library(data.table) library(tidyverse) library(plotly) ui <- fluidPage( mainPanel( plotlyOutput("plot") ) ) server <- function(input, output) { #'*For Graph*' output$plot <- renderPlotly({ one <- df date_range <- one[,base::round(range(`Timestamp`)+c(-60*60, 60*60), unit="hours")] df_regular <- data.table::data.table(`Timestamp` = do.call(seq, c(as.list(date_range), "15 min"))) one_ui <- one[df_regular, ,on = "`Timestamp`", roll = +15*60, nomatch=NULL] one_graph <- one_ui%>% ggplot(aes(x = .[[1]], y = .[[2]])) + geom_line() ggplotly(one_graph) }) } shinyApp( ui, server)
运行应用时出现错误:
unused argument (unit = "hours")
但单独运行数据处理代码时无异常。
错误原因
在data.table的[.data.table操作上下文里,range(Timestamp)+c(-60*60,60*60)的结果会被转换为数值型(POSIXct对象加减数值默认转成秒数),而base::round()只有处理POSIXct/POSIXlt类型时才接受unit参数,处理数值时该参数无效,因此报错。
单独运行时,代码处于普通data.frame上下文,range(Timestamp)返回的POSIXct对象加减数值后仍保持POSIXct类型,round()可以正常识别unit参数,所以不会报错。
修复方案
先确保时间范围调整后仍为POSIXct类型,再调用round(),可以采用两种写法:
写法1:显式转换类型
date_range <- one[, { ts_range <- range(`Timestamp`) adjusted_ts <- ts_range + c(-60*60, 60*60) base::round(as.POSIXct(adjusted_ts, origin = "1970-01-01"), unit = "hours") }]
写法2:使用lubridate包的hours()函数(tidyverse已包含)
date_range <- one[, base::round(range(`Timestamp`) + hours(1), unit = "hours")]
完整修复后的server代码
server <- function(input, output) { #'*For Graph*' output$plot <- renderPlotly({ one <- setDT(df) # 显式转换为data.table,避免上下文混淆 date_range <- one[, base::round(range(`Timestamp`) + hours(1), unit = "hours")] df_regular <- data.table(Timestamp = seq(date_range[1], date_range[2], by = "15 min")) one_ui <- one[df_regular, on = "Timestamp", roll = +15*60, nomatch = NULL] one_graph <- one_ui %>% ggplot(aes(x = Timestamp, y = Heat_Capacity)) + geom_line() ggplotly(one_graph) }) }
额外优化建议
- 显式将
df转换为data.table(setDT(df)),避免data.frame与data.table的操作行为混淆 - 在ggplot中直接使用列名(
x = Timestamp, y = Heat_Capacity),替代.[[1]]、.[[2]],提升代码可读性 - 使用
seq()的by参数生成时间序列,替代do.call(seq, ...),写法更简洁直观
内容的提问来源于stack exchange,提问作者Golem
相关产品推荐
相关产品推荐

