Shiny中基于响应式变量创建投资组合权重的报错问题咨询
错误1:sum报错(invalid 'type' (closure) of argument)修复
该错误的核心原因是响应式变量取值必须加():你定义的weights是reactive()生成的响应式对象,本质是函数,直接写weights调用的是函数本身而非返回的权重向量,所以sum(weights)会触发类型错误。另外你的逻辑中names应为选中的股票标的列表,假设对应input$choices,如果names本身是其他响应式变量也需要加()取值。
错误2:strsplit报错(non-character argument)修复
该错误是因为renderUI生成weights输入框之前,input$weights的值为NULL,直接传入strsplit会触发类型错误;同时要额外兼容用户输入格式异常(比如包含非数字字符、分隔符带空格)的场景,避免转换数值时生成NA影响后续计算。
完整修正代码
权重转换&修正逻辑
# 权重输入框渲染逻辑,增加依赖判断 output$weights <- renderUI({ req(input$choices) # 确保股票选择完成后再渲染输入框 default_wt <- round(1/length(input$choices), digits=2) textInput('weights', 'Enter a vector of weights (comma delimited - sum must be equal to 1)', value = paste(rep(default_wt, times = length(input$choices)), collapse = ", ")) }) # 原始权重转换逻辑,增加异常兼容 weights <- reactive({ req(input$weights) # 等待输入框生成后再执行转换 # 拆分字符串、去除首尾空格后转数值,非数字输入会转为NA wt_vec <- as.numeric(trimws(unlist(strsplit(input$weights, ",")))) return(wt_vec) }) # 权重自动修正逻辑 weights1 <- reactive({ wt_vec <- weights() n_stock <- length(input$choices) # 选中的股票总数 # 异常场景1:权重包含空值/长度和标的数量不匹配,直接返回等权 if(any(is.na(wt_vec)) || length(wt_vec) != n_stock) { return(rep(1/n_stock, n_stock)) } # 异常场景2:权重总和不为1,自动做归一化处理 if(sum(wt_vec) != 1) { return(wt_vec / sum(wt_vec)) } # 合规场景直接返回原权重 return(wt_vec) })
投资组合计算调用逻辑
直接调用weights1()即可,无需额外处理:
returns <- PortfolioReturn(input$choices, stocks, weights1()) output$returns <- renderTable(tail(returns))
注:如果你的
stocks也是响应式变量,调用时需要加()取值,同时建议在计算returns的逻辑前加req(stocks, weights1())避免依赖未加载完成时触发报错。
内容的提问来源于stack exchange,提问作者spec
相关产品推荐
相关产品推荐

