fenguoerbian Cloud2016
一通debug之后可能发现了问题所在,这里预期的做图数据应该是5列(3个座标,1个颜色,1个大小),但是出问题的图的做图数据只有4列。

整个call的顺序是e_scatter_3d --> e_scatter_3d_ --> .build_data2,其中.build_data2源码是

.build_data2 <- function(data, ...) {
  row.names(data) <- NULL
  data <- data |>
    dplyr::select(...)
  
  data <- unname(data)

  apply(data, 1, function(x) {
    list(value = unlist(x, use.names = FALSE))
  })
}

e_scatter_3d_ 调用 .build_data2的时候,使用的语句是

data <- .build_data2(e$x$data[[i]], e$x$mapping$x, y, z, color, size)

以楼主原本的代码而言,可以验证此时在e_scatter_3d_中,colorsize都是字符串“mag",于是原数据在后续的dplyr::select中只被提取到了1次。

而我这个莫名其妙的能让图正常的修改,其实就是碰巧我在数据里加了一列叫做color的列,和这里传入的变量名color相同。所以如果在我那个修改里把新增的列叫做color_not_work,那这个图也不会正常生成。

所以这里的核心就是,dplyr::select(...) 中多次选择同一列,结果只会返回1列。而我那个碰巧的做法,实际是这里提到的模糊的名称使用,而在这里恰好起效了。

另外如果.build_data2(data, ...)...里如果传入的实际上是列名的字符串,那么按照前述链接里的建议的话,为了消除语义中的模糊,可以修改成

dplyr::select(tidyselect::all_of(c(...)))

但是本质上从这里来看,同样的变量被多次选择,只会返回1次,于是做图数据缺了1列。不过消除歧义总是有好处的,比方说在这里,如果原始数据里有"y", "z"这样的列名,那么这里也会优先选取那两列,而不是传入的y,z参数中保存的列名。

    fenguoerbian 所以,本质上,这里是 dplyr 或 tidyselect 包的 BUG?

    因为正常来讲,将一个变量同时映射给气泡的颜色和大小(气泡图的常规做法)是正常的需求。

      fenguoerbian 你可真是位人才。可惜这次 R 会议的报告时间都安排在北京时间的晚上,我这边实在是太早了。我看看后天早上我能不能六点爬起来听你的报告,见识一下本尊。

        Cloud2016

        我觉得这里有好几个问题:

        1. select里多次选择同一列,只返回一次,这个可能是dplyr里确定好的策略了?那么可能就还是落在echarts4r这边来处理如果用户真的多次选择同一个数据的时候,这个构建做图数据的函数该怎么处理。

        2. 另外就是目前的.build_data2函数里,确实是存在语义模糊的缺陷的。

          Cloud2016

          恩,我提交了一个,直接把.build_data.build_data2里的dplyr::select(data, ...)替换成了data[, c(...), drop = FALSE],已经被merge了。

          不过说实话我看utils.R里面有好几处都是用的dplyr::select(...)的做法,也不太好确定是不是这些其它位置也有类似的问题,或者我这样的修改是否带来新的问题。感觉使用中稳妥起见的话,不如就把输入数据里的变量名按照x,y,z,color,size准备一下。

            fenguoerbian 感谢,后面等维护者有空的时候发布新版!本来昨天想继续稍稍吐槽一下 dplyr, 它号称数据操作的语法,提供类似 SQL 的语义,但是又在这和 SQL 不一致,哎 😮‍💨

            fenguoerbian 今天起晚了一点,没赶上你的报告,可惜了。我觉得我们可以举办一个小型 COS 坛友会,应该会比较有意思,比如每个人来一场五分钟闪电报告,像你这里的查虫过程和经验就很值得一讲。

              yihui 没事儿,而且有录屏哈~搞这种闪电报告也是个很好的形式,我就怕自己一下子刹不住车就开始话痨了。

              4 个月 后

              来晚了,echarts4r 的 debug 我常用的办法是用 |> e_inspect(json = TRUE, pretty = TRUE) 来查看输出的设置项,参考ECharts的文档看看有没有错。如果设置项里没有很多JS的函数设置的话,还可以直接把整块设置项丢到Echarts的在线编辑器中查看效果是否正常。再来判断到底是是自己写的,是echarts4r,还是ECharts本身的问题。