我是RShiny的新手。我在R中创建了一个模型,并希望使用RShiny使其易于使用。
它绘制了一些直方图和移动平均图(当前有效),但是当我单击“模拟”按钮并触发反应性值时,我还希望能够下载我的模拟。
由于我正在使用reactValues(),并且使用一些单独的信息进行绘图,因此,我每次点击“模拟按钮”时都会从获得的反应值中创建“ my.download”。但是可下载的.csv文件为我提供了两列(我使用具有5个向量的cbind),并且绝对是奇数。如果我模拟1000个案例,它将给我5000行。如果是2000例,10000行等。
这是我的代码的一部分,与要转换数据的.csv文件有关。
library(data.table)
library(shiny)
library(ggplot2)
### My functions ###
claims.frequency = function(iterations, dist, lambda, size, prob){
freq = rep(NA,iterations)
if(dist == "Poisson"){freq_dt = data.table(i=1:iterations)[,list(freq=rpois(n=1,lambda=lambda)),by=i]}
else if(dist == "Negative Binomial"){freq_dt = data.table(i=1:iterations)[,list(freq=rnbinom(n=1,size=size,prob=prob)),by=i]}
return(freq_dt$freq)
}
claims.severity <- function(frequency,dist,meanlog,sdlog,shape,scale,rate,percentile){
sever = rep(NA,length(frequency))
moving_average = rep(NA,length(frequency))
moving_percentile = rep(NA,length(frequency))
df = rep(NA,length(frequency))
if(dist=="Lognormal"){sever_dt=data.table(i=1:length(frequency))[,list(sever=sum(rlnorm(n=frequency[i],meanlog=meanlog,sdlog=sdlog))),by=i]}
else if(dist=="Gamma"){sever_dt=data.table(i=1:length(frequency))[,list(sever=sum(rgamma(n=frequency[i],shape=shape,rate=rate))),by=i]}
else if(dist=="Exponential"){sever_dt=data.table(i=1:length(frequency))[,list(sever=sum(rexp(n=frequency[i],rate=1/rate))),by=i]}
else if(dist=="Weibull"){sever_dt=data.table(i=1:length(frequency))[,list(sever=sum(rweibull(n=frequency[i],shape=shape,scale=scale))),by=i]}
moving_average_dt = data.table(i=1:length(frequency))[,list(moving_average=mean(sever_dt$sever[1:i])),by=i]
moving_percentile_dt = data.table(i=1:length(frequency))[,list(moving_percentile=quantile(sever_dt$sever[1:i],probs=percentile)),by=i]
df = cbind(frequency,sever_dt$sever,moving_average_dt$moving_average,moving_percentile_dt$moving_percentile)
colnames(df) = c("# Claims","Aggregate Claims Value","Moving Average","Moving Percentile")
return(as.data.frame(df))
}
### UI ###
ui <- fluidPage(
titlePanel('Simulator'),
sidebarPanel(
sliderInput(inputId="n", "Iterations", value = 250500, min = 1000, max = 500000, step = 500, round = TRUE, ticks = TRUE),
radioButtons("freq.dist", "Frequency Distributions:",
c("Poisson (\\(\\lambda\\))" = "P",
"Negative Binomial (n, p)" = "B")),
numericInput("paramfreq1","\\(\\lambda\\), if Poisson; or n, if Negative Binomial",0),
numericInput("paramfreq2","p",0),
radioButtons("sever.dist", "Severity Distributions:",
c("Lognormal (\\(\\mu\\ , \\sigma\\))" = "L",
"Gamma (\\(\\alpha\\ , \\beta\\))" = "G",
"Exponential (\\(\\lambda\\))" = "E",
"Weibull (\\(\\alpha\\ , \\beta\\))" = "W")),
numericInput("paramsever1","\\(\\mu\\), if Lognormal; \\(\\alpha\\), if Gamma or Weibull; or \\(\\lambda\\), if Exponential",0),
numericInput("paramsever2","\\(\\sigma\\), if Lognormal; or \\(\\beta\\), if Gamma or Weibull",0),
actionButton("simulate","Simulate"),
downloadButton('downloadData', 'Download')
)
)
### SERVER ###
server <- function(input, output) {
rv <- reactiveValues(my.freq = 0,
my.total.claims = 0,
my.moving.average = 0,
my.moving.percentile = 0,
my.download = 0)
observeEvent(input$simulate,
{
my.freq <- switch(input$freq.dist,
"P" = claims.frequency(iterations = input$n,
dist = "Poisson",
lambda = input$paramfreq1),
"B" = claims.frequency(iterations = input$n,
dist = "Negative Binomial",
size = input$paramfreq1,
prob = input$paramfreq2))
my.sever <- switch(input$sever.dist,
"L" = claims.severity(frequency = my.freq,
dist = "Lognormal",
meanlog = input$paramsever1,
sdlog = input$paramsever2,
percentile = .995),
"G" = claims.severity(frequency = my.freq,
dist = "Gamma",
shape = input$paramsever1,
rate = input$paramsever2,
percentile = .995),
"E" = claims.severity(frequency = my.freq,
dist = "Exponential",
rate = input$paramsever1,
percentile = .995),
"W" = claims.severity(frequency = my.freq,
dist = "Weibull",
shape = input$paramsever1,
scale = input$paramsever2,
percentile = .995))
rv$my.freq <- as.numeric(my.freq)
rv$my.total.claims <- as.numeric(my.sever$`Aggregate Claims Value`)
rv$my.moving.average <- as.numeric(my.sever$`Moving Average`)
rv$my.moving.percentile <- as.numeric(my.sever$`Moving Percentile`)
rv$my.download <- (as.numeric(cbind(1:length(my.freq), my.sever$`# Claims`,my.sever$`Aggregate Claims Value`,my.sever$`Moving Average`,my.sever$`Moving Percentile`))) ### PROBLEM HERE ###
}
)
output$downloadData <- downloadHandler(
filename = function(){
paste('simulation-', Sys.time(), '.csv', sep='')
},
content = function(file){
write.table(x = rv$my.download, file, dec = "," , sep = ";")
})
}
我希望输出具有正确的列(也包括colnames,但是当我尝试添加它时,它会返回以下错误):
Warning: Error in colnames<-: attempt to set 'colnames' on an object with less than two dimensions
但是我的.csv文件类似于:https://i.imgur.com/zRKLetW.png
预期输出为:https://i.imgur.com/7PJNBny.png
如何解决?
答案 0 :(得分:0)
我不确定这是否是整个问题,但我认为部分问题是您将对cbind()
中的as.numeric()
的调用包装了起来
例如
as.numeric(cbind(1:3, 4:6))
返回数字矢量,其中
cbind(1:3, 4:6)
返回一个矩阵。您还可以使用data.frame(col_name1 = vector1, col_name2 = vector2...)
来确保rv $ mydownload的导出格式正确。