You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:29:51