Lightning Talk @Taiwan R User Group

ggplot2 X Formatter, 2013.10.13

Liang Bo Wang

Taiwan R User Group Anniversary

ggplot2 X Formatter

Liang Bo Wang (亮亮), 2013.10.13

Shared under MIT / CC 3.0 BY License

哪泥!沒聽過 ggplot2?!

Jake Mates "Plug Face - Day 3/365", CC 2.0 BY-NC-SA

只用過 plot()
每次要畫圖的時候

Alice Bartlett "Plug sockets", CC 2.0 BY-NC

用過 ggplot2

Martin Börjesson "Electric plug face", CC 2.0 BY-NC

使用 GDP (PPP) From World Bank

Read in CSV (code here)

            CSV_PATH <- 'path/to/worldbank.csv' 
            df <- read.csv(CSV_PATH, stringsAsFactors=FALSE) 
錯誤在read.table(...) : more columns than column names

結果不如預期……原來 csv 前面多了兩行 => 多加上 skip=2

$ head your.csv
"Data Source","World Development Indicators",

"Country Name","Country Code", ...

各國 GDP 長條圖

這邊只取了 5 國來畫,並且依照 GDP 高低來排序

            library(ggplot2) 
            g <- ggplot(df, aes(x=Country.Code, y=Y2012)) + 
              geom_bar(stat='identity', alpha=.9) + 
              xlim(df$Country.Code)
        

初步結果

  • 感覺還不錯

簡單 Google 後

可以用 expression() 來表達

            breaks <- c(0, seq(from=5e11, to=1.5e12, by=5e11)) 
            labels <- c('0', expression(5%*%10^11), 
                        expression(1.0%*%10^12),
                        expression(1.5%*%10^12))
            g + scale_y_continuous(breaks=breaks, labels=labels)
        

手動定 label

  • 感覺還不錯

如何寫 formatter

吃進一個vector,回傳一個vector。使用時直接 pass 這個函數

my_formatter <- function(l) {
    paste('parsed', l)
}
g + scale_y_continuous(labels=my_formatter)

只要記住自己是一次處理全部的 labels,最後也要回傳全部的 labels

那要如何丟回一個
expression vector?

在這之前,先介紹套件 scales

定義好很多 formatter,用法相同

library(scales)
g + scale_y_continuous(labels=comma) # 12,345,678
g + scale_y_continuous(labels=dollar) # $12,345,678
        
comma dollar

接下來都是黑魔法了…

心法 - 自製回傳 exp. 的 formatter

很多 regex 所以猛醜。分兩個函式寫可以增加更多控制

fancy_scientific_format <- function(l) { 
	# turn in to character string in scientific notation 
	l <- format(l, scientific=TRUE) 
	l <- gsub("0.0+e[+-]0+$", "0", l)  # use '0' instead '0 x 10^0'
	# quote the part before the exponential to keep all the digits 
	l <- gsub("^(.*)e", "'\\1'e", l) 
	l <- gsub("e[+]", "e", l)  # remove the extra '+'
    l <- gsub("e", "%*%10^", l)   # turn the 'e+' into plotmath format 
    l
}
fancy_scientific <- function(l){
    # return as an expression vector
	parse(text=fancy_scientific_format(l)) 
}
default breaks breaks<-c(0, 1e12, 1.3e12)

如果要多加個「$」號,只要再用 gsub() 繼續接 fancy_scientific_format() 即可

        super_fancy_dollar <- function(l){
          parse(text=gsub(
            "^'", "'$", fancy_scientific_format(l)
          ))
        }        
    

終於… (full code here)

THE END

Fork me on Github