看板 R_Language 關於我們 聯絡資訊
[問題類型]: 程式諮詢(我想用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://www.ptt.cc/bbs/R_Language/M.1503486206.A.9C3.html ※ 編輯: clsmbstu (140.112.121.113), 08/23/2017 19:08:12
celestialgod: aes_string 不方便的話,可以考慮wrapr.... 08/23 19:22
celestialgod: 如果你還在想要用column slice方式畫圖,乾脆直接用 08/23 19:23
celestialgod: 原本R的繪圖..... 08/23 19:23
celestialgod: 不知道你說的一般化是什麼,輸入x,y然後繪圖嗎? 08/23 19:24
clsmbstu: 一般化很好舉例啊,例如我要一個shiny app,可以讓使用 08/23 19:49
clsmbstu: 者從vs和am選任一當facet,再任選兩個column畫散佈圖, 08/23 19:51
clsmbstu: aes還有aes_string,但就沒有facet_grid_string 08/23 19:52
clsmbstu: 需要迴圈的例子也很常見,例如我要依第一行當facet、第 08/23 19:53
clsmbstu: 二行為x、第三行起每個奇數行當y,每個存一張圖,用數列 08/23 19:54
clsmbstu: 一下就解決了,偏偏ggplot2就不給這樣玩。 08/23 19:55
celestialgod: facet_grid就用paste + as.formula 08/23 19:57
celestialgod: 迴圈就用names然後取column 08/23 19:57
clsmbstu: 不懂為什麼想要用column slice就得回原本的R繪圖...... 08/23 19:58
celestialgod: 我覺得是沒用R的思維去思考ggplot2的設計QQ 08/23 19:58
celestialgod: 因為只有原本R繪圖才能 plot(mtcars[,1], mtcars[,2 08/23 19:58
celestialgod: lattice或是ggplot2都用data.frame概念去設計 08/23 19:59
celestialgod: table型式資料才比較值觀 08/23 19:59
celestialgod: 兩個vector要做圖,要考慮長度問題、順序問題 08/23 19:59
celestialgod: table就很值觀的,同一列就是pair 08/23 20:00
clsmbstu: 我反而覺得是ggplot跟其它繪圖套件不友善... 08/23 20:00
celestialgod: 如果覺得R不友善,就換個工具吧 我覺得這樣最好 08/23 20:01
clsmbstu: 既然背後都是non-standard evaluation,為什麼不開放直 08/23 20:02
clsmbstu: 接給字串或index數字?反正我一開始都給定data frame了 08/23 20:02
celestialgod: 那為什麼你給data.frame,不用欄名 才奇怪吧 08/23 20:03
clsmbstu: 我想用欄名啊,啊除了aes_string以外又不吃字串 08/23 20:05
celestialgod: 所以我上面跟你說用 formula跟取names做迴圈 08/23 20:05
clsmbstu: names叫出來也是字串啊,不能直接給不是也很奇怪嗎? 08/23 20:05
celestialgod: 還有 formula != NSE... 08/23 20:06
clsmbstu: 而且這裡你給的都只限ggplot,plot_ly function呢? 08/23 20:06
celestialgod: plot_ly沒研究,抱歉 08/23 20:06
celestialgod: 你如果無法接受這樣的設計 還是上面那句話 換工具 08/23 20:07
clsmbstu: 我從來沒有說formula == NSE...... 08/23 20:50
clsmbstu: aes的說明直接就寫了"aes uses non-standard evaluation 08/23 20:52
clsmbstu: to capture the variable names." 08/23 20:52
clsmbstu: 以shiny的例子來說,以下操作就不可能直接實現: 08/23 20:54
clsmbstu: ggplot(mtcars,aes(input$a,input$b))+geom_point()+ 08/23 20:55
clsmbstu: facet_grid(. ~ input$c) 08/23 20:55
clsmbstu: 再來如果用到shiny,我也會想納入plot_ly、leaflet等互 08/23 20:56
clsmbstu: 動性更高的套件,那我也只是好奇大家都怎麼解決。 08/23 20:57
celestialgod: https://gist.github.com/jcheng5/3239667 08/23 20:58
celestialgod: google一下有很多人做這類東西 08/23 20:58
celestialgod: 其他套件應該也同理 08/23 20:58
clsmbstu: 自問自答:若是ggplot2,facet_grid和facet_wrap都支援 08/24 08:59
clsmbstu: 字串輸入,但方式不同,可參考它們的"facets"參數說明 08/24 09:00
※ 編輯: clsmbstu (114.44.107.83), 08/24/2017 09:01:28
clsmbstu: 若是plotly與leaflet,目前看起來可一律用paste和 08/24 09:03
clsmbstu: as.formula將拼湊起來的字串轉換後送給繪圖函數 08/24 09:05
clsmbstu: 常用功能中能夠直接將names函數輸出結果放到繪圖中的, 08/24 09:07
clsmbstu: 目前我看到的只有aes_string以及facet_wrap。 08/24 09:08
clsmbstu: 另外補充說明:因為aes用的就是non-standard evaluation 08/24 09:33
clsmbstu: 所以我上面程式範例中使用eval(parse())的方法,到加入 08/24 09:33
clsmbstu: geom_point()看起來結果都是對的,但只要一facet就會出 08/24 09:34
clsmbstu: 問題,相關的討論之一我放在原文的連結中,主要還是因為 08/24 09:36
clsmbstu: ggplot2內部在繪圖時重新建的data frame會出錯,不過 08/24 09:37
clsmbstu: ggplot2並沒有針對這點寫警告訊息,所以需要自己小心。 08/24 09:38