作者clsmbstu (missing)
看板R_Language
标题[问题] 绘图时不直接使用变数名称
时间Wed Aug 23 19:03:23 2017
[问题类型]:
程式谘询(我想用R 做某件事情,但是我不知道要怎麽用R 写出来)
[软体熟悉度]:
使用者(已经有用R 做过不少作品)
[问题叙述]:
在ggplot2、plotly、leaflet等绘图套件中,
很常直接用变数的名称去做aesthetic mapping,
但是一旦碰到回圈或其它programming需求,
它反而很难一般化。
像是下列的ggplot2绘图范例就有些结果上的差别。
我知道ggplot2套件中有aes_string提供较好的解决方案,
但是其它绘图套件(例如plotly或leaflet)有类似的function吗?
还是它们用non-standard evaluation时不会有问题?
这个问题困扰我满久了,有没有人愿意分享一下经验?
谢谢!
[程式范例]:
# 最一般的做法
ggplot(mtcars, aes(mpg, qsec)) + geom_point() + facet_grid(. ~ am)
# 利用aes_string function
ggplot(mtcars, aes_string("mpg", "qsec")) + geom_point() + facet_grid(. ~ am)
# 以下结果是错误的图
# 用[]指定column
ggplot(mtcars, aes(mtcars[,1], mtcars[,7])) + geom_point() + facet_grid(. ~ am)
# Non-standard evaluation
ggplot(mtcars, aes(eval(parse(text = "mpg"), envir = mtcars),
eval(parse(text = "qsec"), envir = mtcars))) +
geom_point() +
facet_grid(. ~ am)
Stack Overflow相关解答:
https://goo.gl/onbTcz
[关键字]:
Non-standard evaluation, aesthetic mapping
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.112.121.113
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/R_Language/M.1503486206.A.9C3.html
※ 编辑: clsmbstu (140.112.121.113), 08/23/2017 19:08:12
1F:→ celestialgod: aes_string 不方便的话,可以考虑wrapr.... 08/23 19:22
2F:→ celestialgod: 如果你还在想要用column slice方式画图,乾脆直接用 08/23 19:23
3F:→ celestialgod: 原本R的绘图..... 08/23 19:23
4F:→ celestialgod: 不知道你说的一般化是什麽,输入x,y然後绘图吗? 08/23 19:24
5F:→ clsmbstu: 一般化很好举例啊,例如我要一个shiny app,可以让使用 08/23 19:49
6F:→ clsmbstu: 者从vs和am选任一当facet,再任选两个column画散布图, 08/23 19:51
7F:→ clsmbstu: aes还有aes_string,但就没有facet_grid_string 08/23 19:52
8F:→ clsmbstu: 需要回圈的例子也很常见,例如我要依第一行当facet、第 08/23 19:53
9F:→ clsmbstu: 二行为x、第三行起每个奇数行当y,每个存一张图,用数列 08/23 19:54
10F:→ clsmbstu: 一下就解决了,偏偏ggplot2就不给这样玩。 08/23 19:55
11F:→ celestialgod: facet_grid就用paste + as.formula 08/23 19:57
12F:→ celestialgod: 回圈就用names然後取column 08/23 19:57
13F:→ clsmbstu: 不懂为什麽想要用column slice就得回原本的R绘图...... 08/23 19:58
14F:→ celestialgod: 我觉得是没用R的思维去思考ggplot2的设计QQ 08/23 19:58
15F:→ celestialgod: 因为只有原本R绘图才能 plot(mtcars[,1], mtcars[,2 08/23 19:58
16F:→ celestialgod: lattice或是ggplot2都用data.frame概念去设计 08/23 19:59
17F:→ celestialgod: table型式资料才比较值观 08/23 19:59
18F:→ celestialgod: 两个vector要做图,要考虑长度问题、顺序问题 08/23 19:59
19F:→ celestialgod: table就很值观的,同一列就是pair 08/23 20:00
20F:→ clsmbstu: 我反而觉得是ggplot跟其它绘图套件不友善... 08/23 20:00
21F:→ celestialgod: 如果觉得R不友善,就换个工具吧 我觉得这样最好 08/23 20:01
22F:→ clsmbstu: 既然背後都是non-standard evaluation,为什麽不开放直 08/23 20:02
23F:→ clsmbstu: 接给字串或index数字?反正我一开始都给定data frame了 08/23 20:02
24F:→ celestialgod: 那为什麽你给data.frame,不用栏名 才奇怪吧 08/23 20:03
25F:→ clsmbstu: 我想用栏名啊,啊除了aes_string以外又不吃字串 08/23 20:05
26F:→ celestialgod: 所以我上面跟你说用 formula跟取names做回圈 08/23 20:05
27F:→ clsmbstu: names叫出来也是字串啊,不能直接给不是也很奇怪吗? 08/23 20:05
28F:→ celestialgod: 还有 formula != NSE... 08/23 20:06
29F:→ clsmbstu: 而且这里你给的都只限ggplot,plot_ly function呢? 08/23 20:06
30F:→ celestialgod: plot_ly没研究,抱歉 08/23 20:06
31F:→ celestialgod: 你如果无法接受这样的设计 还是上面那句话 换工具 08/23 20:07
32F:→ clsmbstu: 我从来没有说formula == NSE...... 08/23 20:50
33F:→ clsmbstu: aes的说明直接就写了"aes uses non-standard evaluation 08/23 20:52
34F:→ clsmbstu: to capture the variable names." 08/23 20:52
35F:→ clsmbstu: 以shiny的例子来说,以下操作就不可能直接实现: 08/23 20:54
36F:→ clsmbstu: ggplot(mtcars,aes(input$a,input$b))+geom_point()+ 08/23 20:55
37F:→ clsmbstu: facet_grid(. ~ input$c) 08/23 20:55
38F:→ clsmbstu: 再来如果用到shiny,我也会想纳入plot_ly、leaflet等互 08/23 20:56
39F:→ clsmbstu: 动性更高的套件,那我也只是好奇大家都怎麽解决。 08/23 20:57
41F:→ celestialgod: google一下有很多人做这类东西 08/23 20:58
42F:→ celestialgod: 其他套件应该也同理 08/23 20:58
43F:→ clsmbstu: 自问自答:若是ggplot2,facet_grid和facet_wrap都支援 08/24 08:59
44F:→ clsmbstu: 字串输入,但方式不同,可参考它们的"facets"参数说明 08/24 09:00
※ 编辑: clsmbstu (114.44.107.83), 08/24/2017 09:01:28
45F:→ clsmbstu: 若是plotly与leaflet,目前看起来可一律用paste和 08/24 09:03
46F:→ clsmbstu: as.formula将拼凑起来的字串转换後送给绘图函数 08/24 09:05
47F:→ clsmbstu: 常用功能中能够直接将names函数输出结果放到绘图中的, 08/24 09:07
48F:→ clsmbstu: 目前我看到的只有aes_string以及facet_wrap。 08/24 09:08
49F:→ clsmbstu: 另外补充说明:因为aes用的就是non-standard evaluation 08/24 09:33
50F:→ clsmbstu: 所以我上面程式范例中使用eval(parse())的方法,到加入 08/24 09:33
51F:→ clsmbstu: geom_point()看起来结果都是对的,但只要一facet就会出 08/24 09:34
52F:→ clsmbstu: 问题,相关的讨论之一我放在原文的连结中,主要还是因为 08/24 09:36
53F:→ clsmbstu: ggplot2内部在绘图时重新建的data frame会出错,不过 08/24 09:37
54F:→ clsmbstu: ggplot2并没有针对这点写警告讯息,所以需要自己小心。 08/24 09:38