You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R Markdown同一if条件语句内无法渲染两张Plotly 3D散点图的问题排查

问题原因与解决办法

这是R代码块输出逻辑导致的典型问题,我来给你理清楚:

核心原因

在R的代码执行逻辑里,单个代码块(包括if这样的条件块)默认只会返回并输出最后一个表达式的结果。你在同一个if语句里连续写了两个div(plot_ly(...))语句,但R只会把最后那个语句的结果(也就是第二张图的div)传递给R Markdown渲染,第一张图的输出直接被忽略了——这就是为什么只有第二张图能显示。

而你拆分两个if语句时,每个if块都是独立的代码执行单元,各自的最后一个表达式都会被输出,所以两张图都能正常渲染。

两种快速解决办法

1. 用print()显式输出每个图

强制R打印每一个图的输出,而不是只返回最后一个:

{r warning = FALSE, message = FALSE, echo = FALSE, eval = params$subj == "Matematika"}
if(sum(fulldata$Oral_exam) > 0){
 fulldata_color = fulldata %>% mutate(Oral_exam = as.character(Oral_exam), color = recode(Oral_exam, '1' = "red", '0' = "green"))
 # 给第一个图加print()
 print(div(plot_ly(data = fulldata_color, x = ~Long_A_percent, y = ~Long_B_percent, z = ~Short_percent, marker = list(color = ~color), type="scatter3d", mode="markers", text = ~Name, width = 800, height = 800) %>% layout( scene = list(aspectmode = "cube", xaxis = list(range = c(0,100), title = 'Long A (x)'),yaxis = list(range = c(0,100), title = 'Long B (y)'), zaxis = list(range = c(0,100), title = 'Short (z)'))), align = "center"))
 Oral_data = fulldata %>% filter(!is.na(Oral_percent))
 # 第二个图也加print()确保稳定输出
 print(div(plot_ly(data = Oral_data, x = ~Long_A_percent, y = ~Long_B_percent, z = ~Short_percent,color = ~Oral_percent, type="scatter3d", mode="markers", text = ~Name, width = 800, height = 800) %>% layout( scene = list(aspectmode = "cube", xaxis = list(range = c(0,100), title = 'Long A (x)'),yaxis = list(range = c(0,100), title = 'Long B (y)'), zaxis = list(range = c(0,100), title = 'Short (z)'))), align = "center"))
}

2. 将两个图存入列表并返回

R代码块会自动输出列表中的所有元素,把两张图放进一个列表里返回即可:

{r warning = FALSE, message = FALSE, echo = FALSE, eval = params$subj == "Matematika"}
if(sum(fulldata$Oral_exam) > 0){
 fulldata_color = fulldata %>% mutate(Oral_exam = as.character(Oral_exam), color = recode(Oral_exam, '1' = "red", '0' = "green"))
 # 把第一张图存为变量
 plot1 <- div(plot_ly(data = fulldata_color, x = ~Long_A_percent, y = ~Long_B_percent, z = ~Short_percent, marker = list(color = ~color), type="scatter3d", mode="markers", text = ~Name, width = 800, height = 800) %>% layout( scene = list(aspectmode = "cube", xaxis = list(range = c(0,100), title = 'Long A (x)'),yaxis = list(range = c(0,100), title = 'Long B (y)'), zaxis = list(range = c(0,100), title = 'Short (z)'))), align = "center")
 Oral_data = fulldata %>% filter(!is.na(Oral_percent))
 # 把第二张图存为变量
 plot2 <- div(plot_ly(data = Oral_data, x = ~Long_A_percent, y = ~Long_B_percent, z = ~Short_percent,color = ~Oral_percent, type="scatter3d", mode="markers", text = ~Name, width = 800, height = 800) %>% layout( scene = list(aspectmode = "cube", xaxis = list(range = c(0,100), title = 'Long A (x)'),yaxis = list(range = c(0,100), title = 'Long B (y)'), zaxis = list(range = c(0,100), title = 'Short (z)'))), align = "center")
 # 返回包含两个图的列表
 list(plot1, plot2)
}

补充说明

你之前在非if语句里能正常生成多张图,是因为那些语句都是独立的顶级表达式,R会依次输出每个表达式的结果;但进入if块后,整个块变成了一个单一的复合表达式,R只会返回这个复合表达式的最后一个子结果——这就是两者的区别啦。

内容的提问来源于stack exchange,提问作者Bálint L. Tóth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:52:46