【发布时间】:2020-11-24 04:08:52
【问题描述】:
我正在尝试在 bs4TabItem 中使用fluidRow,它最多有 3 个 bs4UserCard 项目。 FluidRows 应该在 for 循环中动态构建,并且最大。 3 bs4UserCard 也应该在 for 循环中动态构建。下面是代码的sn-p。我已经根据其他建议尝试了 UI 和服务器部分中的代码,但它仍然不起作用。
# Get number of rows from dataset
records = nrow(candidatesDF)
# Each row will have max. 3 items
numRows = ceiling(nrow(candidatesDF) / 3)
numRows = c(1:numRows)
count = 0
offset = 3
candidates = bs4TabItem(tabName = "candidates",
for (row in numRows) {
fluidRow(
if (records < offset) {
offset = records
}
for (column in 1:offset) {
count = count + 1
# Convert the names to a more legible format
name = explode(candidatesDF[count, "Candidate"], sep = ", ")
name = paste0(name[2], ' ', name[1])
name = capitalizeStrings(name, all.words = TRUE, lower.back = TRUE)
# Convert the names to the img name format
imgName = explode(name, sep = " ")
imgName = tolower(implode(imgName, "_"))
imgUrl = paste0("img/", imgName, ".png")
# Create a user card on each iteration.
bs4UserCard(
title = name,
subtitle = candidatesDF[count, "Party"],
type = NULL,
width = 4,
src = imgUrl,
status = "danger",
closable = TRUE,
elevation = 4,
imageElevation = 4,
fluidRow(
column(
width = 4,
descriptionBlock(header = "District",
text = capitalizeStrings(candidatesDF[count, "District"],
all.words = TRUE, lower.back = TRUE ))
),
column(
width = 4,
descriptionBlock(header = "Votes",
text = candidatesDF[count, "Votes"])
),
column(
width = 4,
descriptionBlock(header = "Result",
text = candidatesDF[count, "Result"], right_border = FALSE)
)
)
)
records = records - 1
}
)
}
)
使用 if 语句我得到这个错误
Possible missing comma at:
87: for (row in fluidRows) {
^
如果我仅出于测试目的删除 if 语句,我会收到此错误
Warning: Error in explode: Assertion on 'x' failed: May not be NA.
我不确定explode 中的x 如何是NA,因为我在数据集中没有任何NA 值。当我逐行运行代码测试explode函数时,返回了预期的结果,所以我不明白为什么NA。
尽管如此,我的目标是创建 x 数量的 fluidRows,每行最多包含 3 个项目,这些项目的信息是从数据集中动态生成的。 ################################################## ###################### 我已更新代码以反映使用 lapply() 的建议。
# Get number of rows from dataset
records = nrow(candidatesDF)
# Each row will have max. 3 items
numRows = ceiling(nrow(candidatesDF) / 3)
numRows = c(1:numRows)
count = 0
offset = 3
checkOffset = function(records, offset) {
if (records < offset) {
offset = records
}
return(offset)
}
candidates = bs4TabItem(tabName = "candidates",
lapply(numRows, function(r) {
fluidRow(
lapply(1:checkOffset(records, offset), function(c) {
count = count + 1
print(count)
# Convert the names to a more legible format
name = explode(candidatesDF[count, "Candidate"], sep = ", ")
name = paste0(name[2], ' ', name[1])
name = capitalizeStrings(name, all.words = TRUE, lower.back = TRUE)
# Convert the names to the img name format
imgName = explode(name, sep = " ")
imgName = tolower(implode(imgName, "_"))
imgUrl = paste0("img/", imgName, ".png")
records = records - 1
# Create a user card on each iteration.
bs4UserCard(
title = name,
subtitle = candidatesDF[count, "Party"],
type = NULL,
width = 4,
src = imgUrl,
status = "primary",
closable = TRUE,
elevation = 4,
imageElevation = 4,
fluidRow(
column(
width = 4,
descriptionBlock(header = "District",
text = capitalizeStrings(candidatesDF[count, "District"],
all.words = TRUE, lower.back = TRUE ))
),
column(
width = 4,
descriptionBlock(header = "Votes",
text = candidatesDF[count, "Votes"])
),
column(
width = 4,
descriptionBlock(header = "Result",
text = candidatesDF[count, "Result"], right_border = FALSE)
)
)
)
})
)
})
虽然这对接近预期结果有很大帮助,但每个网格中的每张卡片都是相同的。那是因为count变量不递增,record变量也不递增。
提前致谢。
【问题讨论】:
-
你想让这个响应吗?或者只是试图在服务器启动时硬编码元素的数量?
forR 中的循环不返回值。你应该做的是建立一个list()的对象,你想插入到 UI 中,然后将该列表传递给fluidRow()。如果您提供最小的reproducible example,则更容易提供帮助。删除任何对问题不重要的代码。 -
请尝试
lapply而不是for循环。正如 MrFlick 指出的那样,MRE 将有助于识别任何其他问题。 -
@MrFlick 我希望循环使用代表数据集中每一行的索引生成所需的值。我认为我在问题中放置的代码足以重现,所以我不确定要添加什么,并且链接不太清楚,因为有很多可能性。
-
@YBS 我已经删除了 for 循环并用 lapply 替换它们。这达到了一定程度。它能够生成预期的行数和列数,但不会在每次迭代中增加计数变量。因此它将显示相同的用户卡。
-
@Ravi,如果没有完全可重现的代码,很难调试。我会考虑的两个项目是:(1)不需要定义
numRows = c(1:numRows),而是你应该定义lapply(1:numRows, …,(2)对于第二个lapply,请尝试lapply(1:(checkOffset(records, offset)),...