背景:
我有一个名为btnUploadMonthlyfile
的fileInput,用户将使用该文件上传数据文件。上传的数据文件包含名为' Products'的字段。点击btnUploadMonthlyfile
我想显示一个弹出窗口,其中应包含上传文件中每个不同产品的框以及每个产品的框内,我想显示一些与此相关的摘要/指标产品
我在下面写了一段代码来实现相同的
Server.R
observeEvent(input$btnMonthlySanityAppend,
{
sFilePath<-input$btnUploadMonthlyFileForAppend
dtUploadedFile<-as.data.table(read_csv(sFilePath$datapath))
lReturn <- fcnUploadSanityCheckMonthly(dtUploadedFile)
showmodal(modaldialog(
title="Summary",
lReturn$Display
))
}
)
fcnUploadSanityCheckMonthly
用R脚本编写,源自global.R
fcnUploadSanityCheckMonthly <- function(dtUploadedFile){
lUniqueProductsITable <- uniqueN(dtUploadedFile,by = c("Product_ID"))
lUniqueProductName <- unique(dtUploadedFile[,"Product_Name"])
lBoxList <- vector("list",lUniqueProductsITable)
dtToProcess <- copy(dtUploadedFile)
for (i in 1:lUniqueProductsITable){
tags$br()
tags$hr()
sProduct <- lUniqueProductName[i]
dtFilteredOnProduct <- dtToProcess[dtToProcess[["Product_Name"]] %in% sProduct ]
dtDataInfo <- fcnDoSomeProcessingOnDates(dtToProcess)
lDateInformationTable <- box(title=sTitle ,width=12,status = "primary",solidHeader = T,collapsible = T,collapsed = T,
renderDataTable(dtDataInfo ,options=list(scrollX=T))
)
lBoxList[[i]] <- box (width = 12,status = "primary",solidHeader = T,collapsible = T,collapsed = T,
title = lUniqueProductName[i],
lDateInformationTable
)
}
return(list(Display=lBoxList))
}
注意: - fcnDoSomeProcessingOnDates(dtToProcess)
是一个函数,它根据dtToProcess中的Product值进行处理并返回一个表,因此对于每个产品,该函数将返回一个具有不同值的表
问题: 上面的代码根据上传文件中存在的产品数量创建动态框,但每个产品框的框下显示的数据表始终是最后一个,即
lDateInformationTable
的值包含处理数据表的框在循环的最后一次迭代中。
我调试了函数fcnDoSomeProcessingOnDates
,它总是根据产品返回正确的数据表。
对我而言,似乎可能是lDateInformationTable
的值正在作为引用,因为它总是包含在循环的最后一次迭代中处理的数据表。
非常感谢任何帮助!
答案 0 :(得分:3)
之前我遇到过这个问题,使用lapply
代替for循环解决了这个问题。这与以下事实有关:创建的对象不会立即计算,而for循环中的引用变量也会发生变化。因此,尝试用以下内容替换你的for循环:
fcnUploadSanityCheckMonthly <- function(dtUploadedFile){
lUniqueProductsITable <- uniqueN(dtUploadedFile,by = c("Product_ID"))
lUniqueProductName <- unique(dtUploadedFile[,"Product_Name"])
lBoxList <- vector("list",lUniqueProductsITable)
dtToProcess <- copy(dtUploadedFile)
lapply(i in 1:lUniqueProductsITable), function(i)
{ tags$br()
tags$hr()
sProduct <- lUniqueProductName[i]
dtFilteredOnProduct <- dtToProcess[dtToProcess[["Product_Name"]] %in% sProduct ]
dtDataInfo <- fcnDoSomeProcessingOnDates(dtToProcess)
lDateInformationTable <- box(title=sTitle ,width=12,status = "primary",solidHeader = T,collapsible = T,collapsed = T,
renderDataTable(dtDataInfo ,options=list(scrollX=T))
)
}
box(width = 12,status = "primary",solidHeader = T,collapsible = T,collapsed = T,
title = lUniqueProductName[i],
lDateInformationTable
)
}
)
return(list(Display=lBoxList))
}