Возможно, это только я, но я всегда находил 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)
Я не размещаю вывод здесь, потому что это слишком много. Он даже не подходит в консольном буфере!
Как вы можете понять внутреннюю структуру объекта с таким НЕ-компактным дисплеем? Это слишком много деталей, и вы легко теряетесь. Или, по крайней мере, я это делаю.
Ну, ладно. Прежде чем кто-нибудь скажет мне, эй checkout ?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) становится гораздо более проницательным
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
Хотя это гораздо лучше, я все еще чувствую, что это может быть гораздо более проницательными. Таким образом, возможно, кто-то чувствовал то же самое и создал приятную функцию, которая более информативна и по-прежнему компактно отображает информацию. Кто угодно?
Я думаю, что проблема в том, что R делает это так легко определить новую структуру (S3, S4, R6, прото, пользовательский класс и т.д.) с произвольными уровнями nestedness, это трудно сделать по умолчанию ' str', который хорошо работает для всех случаев, особенно когда многие специальные классы не беспокоят определение полезной «str». Однако вы можете переопределить лучшие методы, и поскольку это функция только побочного эффекта, вы вряд ли сломаете что-то другое, кроме дисплеев. Я столкнулся с проблемой (ошибкой) с gtable и поэтому определил ['str.gtable' по своему усмотрению] (https://github.com/baptiste/gridextra/blob/master/R/gtable.r#L12). – baptiste
Еще одна вещь, которую следует учитывать, - это проблеск() от dplyr. – joran
Когда я хочу видеть содержимое объекта модели, я использую 'names', и я смотрю на страницу справки как для функции модели, так и для связанной с ней итоговой функции. Я полагаю, вы могли бы создать какой-то механизм отправки на основе класса, когда я получаю результаты «Hmisc :: описать (obj)» для данных, которые дают мой любимый набор сводных статистических данных, но «names (obj)» для более сложных списков. –