2016-04-02 88 views
1

也許這只是我,但我總是發現str不盡人意。它通常過於冗長,但在許多場合並沒有很多信息。替代'str()`R

事實上,我很喜歡的功能(?str)的描述:

緊顯示的R對象

的內部結構並且特別

在理想情況下該位,每個「基本」結構只顯示一行。

只有這樣,在很多情況下,默認的str實現根本沒有公正的描述。

好的,假設它對data.frame s有效。

library(ggplot2) 
str(mpg) 

> str(mpg) 
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 234 obs. of 11 variables: 
$ manufacturer: chr "audi" "audi" "audi" "audi" ... 
$ model  : chr "a4" "a4" "a4" "a4" ... 
$ displ  : num 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ... 
$ year  : int 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ... 
$ cyl   : int 4 4 4 4 6 6 6 4 4 4 ... 
$ trans  : chr "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ... 
$ drv   : chr "f" "f" "f" "f" ... 
$ cty   : int 18 21 20 21 16 18 18 18 16 20 ... 
$ hwy   : int 29 29 31 30 26 26 27 26 25 28 ... 
$ fl   : chr "p" "p" "p" "p" ... 
$ class  : chr "compact" "compact" "compact" "compact" ... 

然而,對於一個data.frame它不是我想要的信息。例如,除了類別之外,它顯示NA值的數目和唯一值的數目將是非常有用的。

但是對於其他對象,它很快變得難以管理。例如:

gp <- ggplot(mpg, aes(x = displ, y = hwy)) + 
    geom_point() 
str(gp) 

> str(gp) 
List of 9 
$ data  :Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 234 obs. of 11 variables: 
    ..$ manufacturer: chr [1:234] "audi" "audi" "audi" "audi" ... 
    ..$ model  : chr [1:234] "a4" "a4" "a4" "a4" ... 
    ..$ displ  : num [1:234] 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ... 
    ..$ year  : int [1:234] 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ... 
    ..$ cyl   : int [1:234] 4 4 4 4 6 6 6 4 4 4 ... 
    ..$ trans  : chr [1:234] "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ... 
    ..$ drv   : chr [1:234] "f" "f" "f" "f" ... 
    ..$ cty   : int [1:234] 18 21 20 21 16 18 18 18 16 20 ... 
    ..$ hwy   : int [1:234] 29 29 31 30 26 26 27 26 25 28 ... 
    ..$ fl   : chr [1:234] "p" "p" "p" "p" ... 
    ..$ class  : chr [1:234] "compact" "compact" "compact" "compact" ... 
$ layers  :List of 1 
    ..$ :Classes 'LayerInstance', 'Layer', 'ggproto' <ggproto object: Class LayerInstance, Layer> 
    aes_params: list 
    compute_aesthetics: function 
    compute_geom_1: function 
    compute_geom_2: function 
    compute_position: function 
    compute_statistic: function 
    data: waiver 
    draw_geom: function 
    geom: <ggproto object: Class GeomPoint, Geom> 
     aesthetics: function 
     default_aes: uneval 
     draw_group: function 
     draw_key: function 
     draw_layer: function 
     draw_panel: function 
     extra_params: na.rm 
     handle_na: function 
     non_missing_aes: size shape 
     parameters: function 
     required_aes: x y 
     setup_data: function 
     use_defaults: function 
     super: <ggproto object: Class Geom> 
    geom_params: list 
    inherit.aes: TRUE 
    layer_data: function 
    map_statistic: function 
    mapping: NULL 
    position: <ggproto object: Class PositionIdentity, Position> 
     compute_layer: function 
     compute_panel: function 
     required_aes: 
     setup_data: function 
     setup_params: function 
     super: <ggproto object: Class Position> 
    print: function 
    show.legend: NA 
    stat: <ggproto object: Class StatIdentity, Stat> 
     compute_group: function 
     compute_layer: function 
     compute_panel: function 
     default_aes: uneval 
     extra_params: na.rm 
     non_missing_aes: 
     parameters: function 
     required_aes: 
     retransform: TRUE 
     setup_data: function 
     setup_params: function 
     super: <ggproto object: Class Stat> 
    stat_params: list 
    subset: NULL 
    super: <ggproto object: Class Layer> 
$ scales  :Classes 'ScalesList', 'ggproto' <ggproto object: Class ScalesList> 
    add: function 
    clone: function 
    find: function 
    get_scales: function 
    has_scale: function 
    input: function 
    n: function 
    non_position_scales: function 
    scales: list 
    super: <ggproto object: Class ScalesList> 
$ mapping :List of 2 
    ..$ x: symbol displ 
    ..$ y: symbol hwy 
$ theme  : list() 
$ coordinates:Classes 'CoordCartesian', 'Coord', 'ggproto' <ggproto object: Class CoordCartesian, Coord> 
    aspect: function 
    distance: function 
    expand: TRUE 
    is_linear: function 
    labels: function 
    limits: list 
    range: function 
    render_axis_h: function 
    render_axis_v: function 
    render_bg: function 
    render_fg: function 
    train: function 
    transform: function 
    super: <ggproto object: Class CoordCartesian, Coord> 
$ facet  :List of 1 
    ..$ shrink: logi TRUE 
    ..- attr(*, "class")= chr [1:2] "null" "facet" 
$ plot_env :<environment: R_GlobalEnv> 
$ labels  :List of 2 
    ..$ x: chr "displ" 
    ..$ y: chr "hwy" 
- attr(*, "class")= chr [1:2] "gg" "ggplot" 

Whaaattttt ???發生了什麼「緊湊顯示」。這不是緊湊的!

它可能更糟,瘋狂的可怕,例如,對於S4對象。如果你想試試這個:

library(rworldmap) 
newmap <- getMap(resolution = "coarse") 
str(newmap) 

我不會在這裏發佈輸出,因爲它太多了。它甚至不適合控制檯緩衝區!

你怎麼能理解這種非緊湊型顯示器的對象的內部結構?這只是太多的細節,你很容易迷路。或者至少我是。

好吧,好的。之前有人告訴我,嘿結帳?str和調整的論點,這就是我所做的。當然它可以變得更好,但我仍然對str感到失望。

我已經得到了最好的解決方案是創建一個函數,這樣做

if(isS4(obj)){ 
    str(obj, max.level = 2, give.attr = FALSE, give.head = FALSE) 
} else { 
    str(obj, max.level = 1, give.attr = FALSE, give.head = FALSE) 
} 

這顯示緊湊對象的頂層結構。以上(S4對象)的SP對象的輸出變得更加富有洞察力

Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots 
    [email protected] data  :'data.frame': 243 obs. of 49 variables: 
    [email protected] polygons :List of 243 
    .. .. [list output truncated] 
    [email protected] plotOrder :7 135 28 167 31 23 9 66 84 5 ... 
    [email protected] bbox  :-180 -90 180 83.6 
    [email protected] proj4string:Formal class 'CRS' [package "sp"] with 1 slot 

所以,現在你可以看到有5層頂層結構,並且可以進一步單獨調查他們。

以上的ggplot對象類似,現在你可以看到

List of 9 
$ data  :Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 234 obs. of 11 variables: 
$ layers  :List of 1 
$ scales  :Classes 'ScalesList', 'ggproto' 
$ mapping :List of 2 
$ theme  : list() 
$ coordinates:Classes 'CoordCartesian', 'Coord', 'ggproto' 
$ facet  :List of 1 
$ plot_env : 
$ labels  :List of 2 

雖然這是好多了,我還是覺得它可能會更加有見地。所以,也許有人會有同樣的感受,並且創建了一個功能更豐富,功能更強大,並且仍然緊湊地顯示信息的功能。任何人?

+5

我認爲問題是R使得用任意級別的嵌套定義新結構(S3,S4,R6,原型,自定義類等)變得如此簡單,很難做出默認的' str'對於所有情況都適用,尤其是當許多特殊類不需要定義一個有用的'str'時。儘管你可以自由地重新定義更好的方法,並且由於它只是一個副作用函數,所以你不可能破壞顯示以外的其他東西。我遇到了gtable的一個問題(錯誤),並定義了['str.gtable'以滿足我的需要](https://github.com/baptiste/gridextra/blob/master/R/gtable.r#L12)。 – baptiste

+7

要考慮的另一件事是來自dplyr的glimpse()。 – joran

+0

當我想查看模型對象的內容時,我使用'names',並查看模型函數及其相關彙總函數的幫助頁面。我想你可以構建某種基於類的調度機制,當我得到'Hmisc :: describe(obj)'數據框的結果時,它給出了我最喜歡的一組摘要統計信息,而對於更復雜的列表則使用了'names(obj)'。 –

回答

1

在這種情況下,我使用了不太詳細的簡單描述數據結構的tibble軟件包。

library(tibble) 
glimpse(gp)