web-dev-qa-db-ja.com

dplyr:data.frameの各列に関数table()を適用します

Dplyrを使用してdata.frameの各列に関数table()を適用する

私はしばしば、次のようにplyrを使用して、データフレームの各列にテーブル関数を適用します。

library(plyr)
ldply( mtcars, function(x) data.frame( table(x), prop.table( table(x) ) )  )

dplyrでもこれを行うことは可能ですか?

私の試みは失敗します:

mtcars %>%  do( table %>% data.frame() )
melt( mtcars ) %>%  do( table %>% data.frame() )
16
Rasmus Larsen

tidyverse(dplyrおよびpurrr)を使用):

library(tidyverse)

mtcars %>%
    map( function(x) table(x) )
6
Rasmus Larsen

tidyrパッケージに依存しない以下を試すことができます。

mtcars %>% 
   lapply(table) %>% 
   lapply(as.data.frame) %>% 
   Map(cbind,var = names(mtcars),.) %>% 
   rbind_all() %>% 
   group_by(var) %>% 
   mutate(pct = Freq / sum(Freq))
12
Caner

一般に、データフレームのすべての列でtable()を実行したくない場合があります。少なくとも1つの変数が一意であり(idフィールド)、非常に長い出力が生成されるためです。ただし、group_by()およびtally()を使用して、dplyrチェーンの頻度表を取得できます。または、count()を実行するgroup_by()を使用できます。

_> mtcars %>% 
    group_by(cyl) %>% 
    tally()
> # mtcars %>% count(cyl)

Source: local data frame [3 x 2]

  cyl  n
1   4 11
2   6  7
3   8 14
_

双方向度数表を作成する場合は、複数の変数でグループ化します。

_> mtcars %>% 
    group_by(gear, cyl) %>% 
    tally()
> # mtcars %>% count(gear, cyl)
_

tidyrパッケージのspread()を使用すると、2つの変数が入力されたときに、双方向出力をtable()での受信に使用される出力に変換できます。

9
josiekre

Canerによる解決策は機能しませんでしたが、comenter akrun(クレジットは彼に提供されます)から、この解決策はうまく機能しました。また、それをデモするためにはるかに大きいティブルを使用しています。また、パーセントの降順で注文を追加しました。

library(nycflights13);dim(flights)

tte<-gather(flights, Var, Val) %>% 
group_by(Var) %>% dplyr::mutate(n=n()) %>% 
group_by(Var,Val) %>% dplyr::mutate(n1=n(), Percent=n1/n)%>%
arrange(Var,desc(n1) %>% unique()
0
userJT