R中`str()`的替代

eli*_*ing 5 r

或许只是我一个人,却总觉得str不尽如人意。它通常过于冗长,但在许多情况下却没有提供太多信息。

我真的很喜欢函数 ( ?str)的描述:

简洁地展示一个R对象的内部结构

尤其是这一点

理想情况下,每个“基本”结构只显示一行。

只是,在许多情况下,默认str实现根本不符合这种描述。

好吧,假设它对data.frames部分有好处。

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" ...
Run Code Online (Sandbox Code Playgroud)

然而,对于 adata.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"
Run Code Online (Sandbox Code Playgroud)

Whaaattttt ???,“紧凑显示”发生了什么。这不紧凑!

例如,对于 S4 对象,情况可能更糟,疯狂可怕。如果你想试试这个:

library(rworldmap)
newmap <- getMap(resolution = "coarse")
str(newmap)
Run Code Online (Sandbox Code Playgroud)

我不在这里发布输出,因为它太多了。它甚至不适合控制台缓冲区!

你怎么可能理解这样一个非紧凑型显示器的物体的内部结构?只是细节太多,你很容易迷路。或者至少我是这样做的。

好吧,好吧。在有人告诉我之前,嘿结账?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)
}
Run Code Online (Sandbox Code Playgroud)

这将紧凑地显示对象的顶级结构。上面 sp 对象(S4 对象)的输出变得更有见地

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

所以现在您可以看到有 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
Run Code Online (Sandbox Code Playgroud)

虽然这要好得多,但我仍然觉得它可以更有见地。所以,也许有人有同样的感觉,并创建了一个很好的功能,该功能提供更多信息,并且仍然紧凑地显示信息。任何人?

pau*_*eba 5

在这种情况下,我使用 tibble 包中的一瞥,它不那么冗长,并且对数据结构进行了简要描述。

library(tibble)
glimpse(gp)
Run Code Online (Sandbox Code Playgroud)