我正在尝试为平板随机化创建一个简单的应用程序。它需要一些参数作为用户的输入(如主题数量,访问次数,重复次数)。
在server.R中我需要一个循环来创建具有随机主题ID号的板。稍后我需要使用列表的元素进行其他计算和绘图。我无法在Shiny中使用此功能。否则效果很好。从plate.w.subjects< - list()
开始,代码不起作用这是server.R代码:
n.subjects <- reactive({ as.numeric(input$n.subjects) })
n.visits <- reactive({ as.numeric(input$n.visits) })
n.replicates <- reactive({ as.numeric(input$n.replicates) })
n.buffers <- reactive({ as.numeric(input$n.buffers) })
n.ipc <- reactive({ as.numeric(input$n.ipc) })
n.plates <- reactive({ ceiling((n.subjects()*n.visits()*n.replicates())/(n.wells-sum(n.buffers(),n.ipc()))) })
subject.ids <- reactive({ seq(1, n.subjects()) })
## other calculations here
plates.w.subjects <- list()
plates.data <- reactive({
for(i in 1:n.plates()) {
local({
if (i == 1) {
used.samples <- NA
left.samples <- subject.ids()
} else {
used.samples <- melt(plates.w.subjects)[,1]
left.samples <- setdiff(subject.ids(), used.samples)
}
if(length(left.samples) > max.subjects.plate()) {
c <- sample(left.samples, max.subjects.plate(), replace=FALSE, prob=NULL)
} else {
c <- sample(left.samples, length(left.samples), replace=FALSE, prob=NULL)
}
name <- paste0('Plate.', i)
tmp <- list(subj.ids = c)
plates.w.subjects[[name]] <- tmp
#rm(tmp,name,c,used.samples,left.samples)
})
}
})
output$result <- renderPrint({
plates.data()$plates.w.subjects[[1]]
})
理想情况下,结果应为:
$Plate.1
$Plate.1$subj.ids
[1] 23 16 13 20 24 10 19 25 3 21 4 12 9
$Plate.2
$Plate.2$subj.ids
[1] 14 22 8 18 2 17 6 11 1 15 5 7
我看到一些使用'本地'或'lapply'的解决方案,但我不能让任何一个工作.. 非常感谢任何帮助! 谢谢! 玛利亚
答案 0 :(得分:0)
不确定这是否能完全解决问题,但我把它拆开试图找到你的错误。
plates.w.subjects <- list()
name <- paste0('Plate.', 1) # i = 1
tmp <- list(subj.ids = c(100, 200))
(plates.w.subjects[[name]] <- tmp)
name <- paste0('Plate.', 2) # i = 2
tmp <- list(subj.ids = c(2000, 3000))
(plates.w.subjects[[name]] <- tmp)
您可能不想使用plates.data()$plates.w.subjects[[1]]
,而是尝试使用plates.w.subjects
。
plates.w.subjects
# $Plate.1
# $Plate.1$subj.ids
# [1] 100 200
# $Plate.2
# $Plate.2$subj.ids
# [1] 2000 3000
plates.w.subjects[[1]]
# $subj.ids
# [1] 100 200
!注意:另外,最好避免c = ...
,因为它可能会与c(100,200)
组合冲突。
答案 1 :(得分:0)
我不得不将代码分解成更多部分以使其完成我需要的工作。如果i == 1进入一个单独的块,我最终分开了。这是有效的。不确定编程方面的效率如何..
plates.w.subjects.1 <- reactive({
sample(subject.ids(), max.subjects.plate(), replace=FALSE, prob=NULL)
})
plates.w.subjects <- reactive({
plates.data <- list()
plates.data$Plate.1 <- list(subj.ids = plates.w.subjects.1())
for(i in 2:n.plates()) {
used.samples <- melt(plates.data)[,1]
left.samples <- setdiff(subject.ids(), used.samples)
if(length(left.samples) > max.subjects.plate()) {
z <- sample(left.samples, max.subjects.plate(), replace=FALSE, prob=NULL)
} else {
z <- sample(left.samples, length(left.samples), replace=FALSE, prob=NULL)
}
tmp <- list(subj.ids = z)
plates.data[[paste0('Plate.', i)]] <- tmp
}
plates.data
})
output$result <- renderPrint({
plates.w.subjects()
})