[英]Creating variable based on reactive one in shiny
我正在開發 shiny 應用程序,它計算基本的投資組合統計數據。 除了股票,用戶還可以定義要分配給特定股票的權重 - 因此具有權重的向量的長度應該等於選擇向量,並且總和為 1。
我已經在服務器 function 中編寫了這部分代碼,因為我希望它在單擊下載按鈕后出現:
ui:
uiOutput("weights")
server:
output$weights <- renderUI({
textInput('weights', 'Enter a vector of weights (comma delimited - sum must be equal to 1)',
value=paste(rep(round(1/length(input$choices),digits=2), times=length(input$choices)),
collapse=", "))})
weights <- reactive(
as.numeric(unlist(strsplit(input$weights, ","))))
以上部分工作 - 我在 ui function 中做了一些測試輸出,所以我可以看看一切是否正常。 它還將用戶以特定方式(逗號分隔)輸入的字符向量轉換為數字(我想不出其他方式來做到這一點)。 但是,如果用戶提供了錯誤的權重向量(例如當總和不等於 1 或長度不正確時),我需要讓應用程序修復權重向量。 如果這是反應式的,那將是完美的,因此進一步的計算將自動執行。 但是,當我嘗試創建包含修復錯誤的 if 語句的變量時:
weights1 <- reactive({
(if(length(weights)==length(names) & sum(weights)==1) weights else
if(length(weights)==length(names) & sum(weights)!=1) c(weights/sum(weights)) else
c(rep(1/length(names),length(names))))})
我收到一個錯誤:
警告:總和錯誤:參數的無效“類型”(閉包)
有什么辦法嗎?
在嘗試了@stefan 提出的解決方案后,我遇到了另一個問題,現在我收到了消息:
警告:strsplit 中的錯誤:非字符參數
當我嘗試使用 weights1() 向量執行計算時。
PortfolioReturn <- function(names, stocks, weights)
{
# portfolio = close_price*weight
portfolio <- as.data.frame(mapply('*', stocks[,-1], weights))
#row.names(portfolio) <- stocks$Date
# daily return = (P(t) - P(t-1)) / P(t-1)
# it is the percentage price difference
returns <- as.data.frame(apply(portfolio, 2, diff.xts, lag = 1)/apply(portfolio, 2, DataCombine::shift, shiftBy = -1, reminder = FALSE))
returns
# cumulate daily returns
returns$cum_returns <- as.vector(apply(returns, 1, sum))
return(returns)
}
((((
weightsx <- rep(round(1/length(input$choices),digits=2), times=length(input$choices))
returns <- PortfolioReturn(input$choices, stocks, weights1())
output$returns <- renderTable(tail(returns))
代碼在使用 weightsx 向量時有效,即為所選投資組合中的每只股票賦予相同的權重。 我猜這是從字符到數字的向量轉換的問題,但我不知道如何解決這個問題。
正如@stefan 所指出的,可以在末尾添加 () 訪問反應值(就像調用函數一樣)。
weights1 <- reactive({
(if(length(weights())==length(names) & sum(weights())==1) weights() else
if(length(weights())==length(names) & sum(weights())!=1) c(weights()/sum(weights())) else
c(rep(1/length(names),length(names))))})
如果名稱變量是反應性的,則相同,這在代碼中未指定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.