tidyr 0.3を使ってみる
tidyrのバージョンが上がってました。
リリースノート
Release tidyr 0.3.0 · hadley/tidyr · GitHub
主な変更点
complete()
New
complete()
provides a wrapper aroundexpand()
,left_join()
andreplace_na()
for a common task: completing a data frame with missing combinations of variables.
これはちょっと何を言ってるかわからない...。
出所はこのSOの質問みたいです。
以下のようなデータがあったときに、groupid
とitemid
の全組み合わせが見たいとします。具体的には、「groupid
がone
でitemid
が1
のvalue
は3
」「groupid
がone
でitemid
が2
のvalue
は存在しない」...という感じです。
df1 <- data.frame(groupid = c("one","one","one","two","two","two", "one"), value = c(3,2,1,2,3,1,22), itemid = c(1:6, 6)) df1 #> groupid value itemid #> 1 one 3 1 #> 2 one 2 2 #> 3 one 1 3 #> 4 two 2 4 #> 5 two 3 5 #> 6 two 1 6 #> 7 one 22 6
すべての値の組み合わせをつくるのは、expand()
という関数が用意されています。以下のような感じです。よさそうです。
expand(df1, itemid, groupid) #> Source: local data frame [12 x 2] #> #> itemid groupid #> (dbl) (fctr) #> 1 1 one #> 2 1 two #> 3 2 one #> 4 2 two #> 5 3 one #> 6 3 two ...
ただ、ここにvalue
を紐づけるには、元のdf1
をdplyr::left_join()
する必要があります。ちょっと冗長な感じがします。
expand(df1, itemid, groupid) %>% left_join(df1, by = c("itemid", "groupid")) #> Source: local data frame [12 x 3] #> #> itemid groupid value #> (dbl) (fctr) (dbl) #> 1 1 one 3 #> 2 1 two NA #> 3 2 one 2 ...
これをcomplete()
を使えば一発でできます。
complete(df1, itemid, groupid) #> Source: local data frame [12 x 3] #> #> itemid groupid value #> (dbl) (fctr) (dbl) #> 1 1 one 3 #> 2 1 two NA #> 3 2 one 2 ...
NA
を値で置き換えるには、fill
という引数を使います。
complete(df1, itemid, groupid, fill = list(value = 0)) #> Source: local data frame [12 x 3] #> #> itemid groupid value #> (dbl) (fctr) (dbl) #> 1 1 one 3 #> 2 1 two 0 #> 3 2 one 2 ...
使いどころがぱっと思いつきませんが、まあ便利そうな関数ではあります。
fill()
fill()
fills in missing values in a column with the last non-missing value (#4).
NA
を、一番直前の値で埋めてくれます。
df <- data.frame(Month = 1:12, Year = c(2000, rep(NA, 11))) df #> Month Year #> 1 1 2000 #> 2 2 NA #> 3 3 NA #> 4 4 NA ... df %>% fill(Year) #> Month Year #> 1 1 2000 #> 2 2 2000 #> 3 3 2000 #> 4 4 2000 ...
これはおなじみdplyr::select()
と同じ記法が使えます。
df <- data.frame(x = c(1, rep(NA, 10)), y = c(1:2, rep(NA, 9)), z = c(1:3, rep(NA, 8))) df #> x y z #> 1 1 1 1 #> 2 NA 2 2 #> 3 NA NA 3 #> 4 NA NA NA ... fill(df, -x) #> x y z #> 1 1 1 1 #> 2 NA 2 2 #> 3 NA 2 3 #> 4 NA 2 3 ...
replace_na()
New
replace_na()
makes it easy to replace missing values with something meaningful for your data.
これほしかった! その名の通りNA
を置き換えてくれます。
第一引数にdata.frameを渡し、第二引数に置き換える値をlistで渡します。
df <- data_frame(x = c(1, 2, NA), y = c("a", NA, "b")) df %>% replace_na(list(x = 0, y = "unknown")) #> Source: local data frame [3 x 2] #> #> x y #> (dbl) (chr) #> 1 1 a #> 2 2 unknown #> 3 0 b
なんとなく忘れてmutate()
の中で使ってエラーになったりしそう...。
nest()
nest()
is the complement ofunnest()
(#3).
unnest()
は前からあった関数で、data.frameの中にネストして入っているlistやdata.frameを展開します。
df <- data.frame( x = 1:2, y = list(data.frame(a = 1:10), data.frame(a = 11:20)) ) df #> Source: local data frame [2 x 2] #> #> x y #> (int) (chr) #> 1 1 <int[5]> #> 2 2 <int[5]> unnest(df, y) #> Source: local data frame [10 x 2] #> #> x y #> (int) (int) #> 1 1 1 #> 2 1 2 #> 3 1 3 #> 4 1 4 ...
nest()
は逆に、data.frame()の中にネストをつくります。baseのsplit()
とかdplyr::group_by()
がイメージに近いです。たぶん。
iris %>% nest(-Species) #> Source: local data frame [3 x 5] #> Groups: <by row> #> #> Species Sepal.Length Sepal.Width Petal.Length Petal.Width #> (fctr) (chr) (chr) (chr) (chr) #> 1 setosa <dbl[50]> <dbl[50]> <dbl[50]> <dbl[50]> #> 2 versicolor <dbl[50]> <dbl[50]> <dbl[50]> <dbl[50]> #> 3 virginica <dbl[50]> <dbl[50]> <dbl[50]> <dbl[50]>
感想
細かいけど便利なのが増えてきた気がします。
問題は、必要なときにtidyrの関数を思い出せるかということ。。いつもどれがどの関数か忘れてしまいます。