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
相关产品推荐
相关产品推荐

