[問題] 繪圖時不直接使用變數名稱

看板R_Language作者 (missing)時間6年前 (2017/08/23 19:03), 6年前編輯推噓0(0054)
留言54則, 2人參與, 最新討論串1/1
[問題類型]: 程式諮詢(我想用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

08/23 19:22, , 1F
aes_string 不方便的話,可以考慮wrapr....
08/23 19:22, 1F

08/23 19:23, , 2F
如果你還在想要用column slice方式畫圖,乾脆直接用
08/23 19:23, 2F

08/23 19:23, , 3F
原本R的繪圖.....
08/23 19:23, 3F

08/23 19:24, , 4F
不知道你說的一般化是什麼,輸入x,y然後繪圖嗎?
08/23 19:24, 4F

08/23 19:49, , 5F
一般化很好舉例啊,例如我要一個shiny app,可以讓使用
08/23 19:49, 5F

08/23 19:51, , 6F
者從vs和am選任一當facet,再任選兩個column畫散佈圖,
08/23 19:51, 6F

08/23 19:52, , 7F
aes還有aes_string,但就沒有facet_grid_string
08/23 19:52, 7F

08/23 19:53, , 8F
需要迴圈的例子也很常見,例如我要依第一行當facet、第
08/23 19:53, 8F

08/23 19:54, , 9F
二行為x、第三行起每個奇數行當y,每個存一張圖,用數列
08/23 19:54, 9F

08/23 19:55, , 10F
一下就解決了,偏偏ggplot2就不給這樣玩。
08/23 19:55, 10F

08/23 19:57, , 11F
facet_grid就用paste + as.formula
08/23 19:57, 11F

08/23 19:57, , 12F
迴圈就用names然後取column
08/23 19:57, 12F

08/23 19:58, , 13F
不懂為什麼想要用column slice就得回原本的R繪圖......
08/23 19:58, 13F

08/23 19:58, , 14F
我覺得是沒用R的思維去思考ggplot2的設計QQ
08/23 19:58, 14F

08/23 19:58, , 15F
因為只有原本R繪圖才能 plot(mtcars[,1], mtcars[,2
08/23 19:58, 15F

08/23 19:59, , 16F
lattice或是ggplot2都用data.frame概念去設計
08/23 19:59, 16F

08/23 19:59, , 17F
table型式資料才比較值觀
08/23 19:59, 17F

08/23 19:59, , 18F
兩個vector要做圖,要考慮長度問題、順序問題
08/23 19:59, 18F

08/23 20:00, , 19F
table就很值觀的,同一列就是pair
08/23 20:00, 19F

08/23 20:00, , 20F
我反而覺得是ggplot跟其它繪圖套件不友善...
08/23 20:00, 20F

08/23 20:01, , 21F
如果覺得R不友善,就換個工具吧 我覺得這樣最好
08/23 20:01, 21F

08/23 20:02, , 22F
既然背後都是non-standard evaluation,為什麼不開放直
08/23 20:02, 22F

08/23 20:02, , 23F
接給字串或index數字?反正我一開始都給定data frame了
08/23 20:02, 23F

08/23 20:03, , 24F
那為什麼你給data.frame,不用欄名 才奇怪吧
08/23 20:03, 24F

08/23 20:05, , 25F
我想用欄名啊,啊除了aes_string以外又不吃字串
08/23 20:05, 25F

08/23 20:05, , 26F
所以我上面跟你說用 formula跟取names做迴圈
08/23 20:05, 26F

08/23 20:05, , 27F
names叫出來也是字串啊,不能直接給不是也很奇怪嗎?
08/23 20:05, 27F

08/23 20:06, , 28F
還有 formula != NSE...
08/23 20:06, 28F

08/23 20:06, , 29F
而且這裡你給的都只限ggplot,plot_ly function呢?
08/23 20:06, 29F

08/23 20:06, , 30F
plot_ly沒研究,抱歉
08/23 20:06, 30F

08/23 20:07, , 31F
你如果無法接受這樣的設計 還是上面那句話 換工具
08/23 20:07, 31F

08/23 20:50, , 32F
我從來沒有說formula == NSE......
08/23 20:50, 32F

08/23 20:52, , 33F
aes的說明直接就寫了"aes uses non-standard evaluation
08/23 20:52, 33F

08/23 20:52, , 34F
to capture the variable names."
08/23 20:52, 34F

08/23 20:54, , 35F
以shiny的例子來說,以下操作就不可能直接實現:
08/23 20:54, 35F

08/23 20:55, , 36F
ggplot(mtcars,aes(input$a,input$b))+geom_point()+
08/23 20:55, 36F

08/23 20:55, , 37F
facet_grid(. ~ input$c)
08/23 20:55, 37F

08/23 20:56, , 38F
再來如果用到shiny,我也會想納入plot_ly、leaflet等互
08/23 20:56, 38F

08/23 20:57, , 39F
動性更高的套件,那我也只是好奇大家都怎麼解決。
08/23 20:57, 39F

08/23 20:58, , 40F

08/23 20:58, , 41F
google一下有很多人做這類東西
08/23 20:58, 41F

08/23 20:58, , 42F
其他套件應該也同理
08/23 20:58, 42F

08/24 08:59, , 43F
自問自答:若是ggplot2,facet_grid和facet_wrap都支援
08/24 08:59, 43F

08/24 09:00, , 44F
字串輸入,但方式不同,可參考它們的"facets"參數說明
08/24 09:00, 44F
※ 編輯: clsmbstu (114.44.107.83), 08/24/2017 09:01:28

08/24 09:03, , 45F
若是plotly與leaflet,目前看起來可一律用paste和
08/24 09:03, 45F

08/24 09:05, , 46F
as.formula將拼湊起來的字串轉換後送給繪圖函數
08/24 09:05, 46F

08/24 09:07, , 47F
常用功能中能夠直接將names函數輸出結果放到繪圖中的,
08/24 09:07, 47F

08/24 09:08, , 48F
目前我看到的只有aes_string以及facet_wrap。
08/24 09:08, 48F

08/24 09:33, , 49F
另外補充說明:因為aes用的就是non-standard evaluation
08/24 09:33, 49F

08/24 09:33, , 50F
所以我上面程式範例中使用eval(parse())的方法,到加入
08/24 09:33, 50F

08/24 09:34, , 51F
geom_point()看起來結果都是對的,但只要一facet就會出
08/24 09:34, 51F

08/24 09:36, , 52F
問題,相關的討論之一我放在原文的連結中,主要還是因為
08/24 09:36, 52F

08/24 09:37, , 53F
ggplot2內部在繪圖時重新建的data frame會出錯,不過
08/24 09:37, 53F

08/24 09:38, , 54F
ggplot2並沒有針對這點寫警告訊息,所以需要自己小心。
08/24 09:38, 54F
文章代碼(AID): #1PdM3-d3 (R_Language)
文章代碼(AID): #1PdM3-d3 (R_Language)