【问题标题】:suppress print output sf object抑制打印输出 sf 对象
【发布时间】:2020-11-03 21:55:41
【问题描述】:

我正在尝试将 head 的等价物保存在列表中。当您在 sf 类上使用 head 时,它会向控制台打印一些关于数据周长的误导性信息,请参阅 bbox 信息与原始信息不同:

library(sf)
library(tidyverse)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
# Simple feature collection with 100 features and 14 fields
# geometry type:  MULTIPOLYGON
# dimension:      XY
# bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
# geographic CRS: NAD27


head(nc)
# Simple feature collection with 6 features and 14 fields
# geometry type:  MULTIPOLYGON
# dimension:      XY
# bbox:           xmin: -81.74107 ymin: 36.07282 xmax: -75.77316 ymax: 36.58965
# geographic CRS: NAD27
#    AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79                       geometry
# 1 0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1      10  1364     0      19 MULTIPOLYGON (((-81.47276 3...
# 2 0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0      10   542     3      12 MULTIPOLYGON (((-81.23989 3...
# 3 0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5     208  3616     6     260 MULTIPOLYGON (((-80.45634 3...
# 4 0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1     123   830     2     145 MULTIPOLYGON (((-76.00897 3...
# 5 0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9    1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3...
# 6 0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7     954  1838     5    1237 MULTIPOLYGON (((-76.74506 3...

那是因为我认为它为前 6 次观察而不是整个数据框计算 bbox。作为替代方案,您可以运行以下print(请参阅bbox 与完整数据集相同):

print(nc, n = getOption("sf_max_print", default = 6))
# Simple feature collection with 100 features and 14 fields
# geometry type:  MULTIPOLYGON
# dimension:      XY
# bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
# geographic CRS: NAD27
# First 6 features:
#    AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79                       geometry
# 1 0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1      10  1364     0      19 MULTIPOLYGON (((-81.47276 3...
# 2 0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0      10   542     3      12 MULTIPOLYGON (((-81.23989 3...
# 3 0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5     208  3616     6     260 MULTIPOLYGON (((-80.45634 3...
# 4 0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1     123   830     2     145 MULTIPOLYGON (((-76.00897 3...
# 5 0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9    1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3...
# 6 0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7     954  1838     5    1237 MULTIPOLYGON (((-76.74506 3...

如何在不打印到控制台的情况下将此打印对象保存在列表中(稍后将在函数中使用)?

当我粗鲁地将它放在一个列表中而不试图抑制它按预期打印的输出时:

a <- lst(dim(nc), head_sf = print(nc, n = getOption("sf_max_print", default = 6)))
# Simple feature collection with 100 features and 14 fields
# geometry type:  MULTIPOLYGON
# dimension:      XY
# bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
# geographic CRS: NAD27
# First 6 features:
#    AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79                       geometry
# 1 0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1      10  1364     0      19 MULTIPOLYGON (((-81.47276 3...
# 2 0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0      10   542     3      12 MULTIPOLYGON (((-81.23989 3...
# 3 0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5     208  3616     6     260 MULTIPOLYGON (((-80.45634 3...
# 4 0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1     123   830     2     145 MULTIPOLYGON (((-76.00897 3...
# 5 0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9    1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3...
# 6 0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7     954  1838     5    1237 MULTIPOLYGON (((-76.74506 3...

我以为invisiblesink 会抑制输出,但我想不通,这些都不起作用:

a <- invisible(lst(dim(nc), head_sf = print(nc, n = getOption("sf_max_print", default = 6))))
a <- lst(dim(nc), head_sf = invisible(print(nc, n = getOption("sf_max_print", default = 6))))
a <- lst(dim(nc), invisible(head_sf = print(nc, n = getOption("sf_max_print", default = 6))))

有什么建议吗?谢谢

编辑: 使用 invisiblecapture.output 几乎可以得到我想要的(我最初发布此内容时输出不正确 - 我的错误)

    a <- lst(dim(nc), invisible(capture.output(head_sf = print(nc, n = getOption("sf_max_print", default = 6)))))
    a
    $`dim(nc)`
[1] 100  15

$`invisible(...)`
 [1] "Simple feature collection with 100 features and 14 fields"                                                                               
 [2] "geometry type:  MULTIPOLYGON"                                                                                                            
 [3] "dimension:      XY"                                                                                                                      
 [4] "bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965"                                                           
 [5] "geographic CRS: NAD27"                                                                                                                   
 [6] "First 6 features:"                                                                                                                       
 [7] "   AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79                       geometry"
 [8] "1 0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1      10  1364     0      19 MULTIPOLYGON (((-81.47276 3..."
 [9] "2 0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0      10   542     3      12 MULTIPOLYGON (((-81.23989 3..."
[10] "3 0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5     208  3616     6     260 MULTIPOLYGON (((-80.45634 3..."
[11] "4 0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1     123   830     2     145 MULTIPOLYGON (((-76.00897 3..."
[12] "5 0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9    1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3..."
[13] "6 0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7     954  1838     5    1237 MULTIPOLYGON (((-76.74506 3..." 

【问题讨论】:

  • 也许使用 quote 来禁止打印到控制台,然后在 a_quote$head_sf 上使用 eval: a_quote &lt;- quote(lst(dim(nc), head_sf = print(nc, n = getOption("sf_max_print", default = 6)))); eval(a_quote$head_sf)?
  • @Chris 谢谢,这很有用,但是当我在函数中尝试它时,它无法按预期工作mylist &lt;- lst(nc); b &lt;- lapply(mylist, function(x) { a_quote &lt;- quote(lst(dims = dim(x), head_sf = print(x, n = getOption("sf_max_print", default = 6)))) eval(a_quote$dims) eval(a_quote$head_sf) } );b,当我调用b 时,它会自动打印但不会评估dims 或@987654346 @?
  • 似乎是一种范围界定的事情。 Quote 将所有内容包装起来以供以后处理,并禁止打印到控制台,并保留正确的 bbox。现在,把这一切都扔进lapply(头疼,眼睛流血),也许想要do.calleval(s),或者这可能是mapply土地。总之,我们正在寻找 =c)))) ;eval(a_quo 之前或之后(或之间)的东西。好的,我会玩,抱歉,这不是更确定的。

标签: r printing output sf


【解决方案1】:

可能是一种不好的方法,不知道返回值将受到什么进一步处理(我觉得单独的暗淡,head_sf 是不可取的),如果您讨厌循环,但使用invisible(capture.output 的变体,则尤其糟糕如看到suppress auto console output

library(sf)
library(tidyverse)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
nc1 <- nc
nc2 <- nc
nc3 <- nc
nc_lst <- list(nc1, nc2, nc3)

prepare_sf_head_for_further_process_loop3 <- function(nc_lst) { 
a_quote <- list()
for(i in 1:length(nc_lst)) {
invisible(capture.output(a_quote[[i]] <- list(dims = dim(nc_lst[[i]]), head_sf = print(nc_lst[[i]], n = getOption('sf_max_print', default = 6)))))
}
return(a_quote)
}


>b3 <- prepare_sf_head_for_further_process_loop3(nc_lst)
>b3
[[1]]
[[1]]$dims
[1] 100  15

[[1]]$head_sf
Simple feature collection with 100 features and 14 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
geographic CRS: NAD27
First 10 features:
    AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74
1  0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1
2  0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0
3  0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5
4  0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1
5  0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9
6  0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7
7  0.062     1.547  1834    1834      Camden 37029  37029       15   286     0
8  0.091     1.284  1835    1835       Gates 37073  37073       37   420     0
9  0.118     1.421  1836    1836      Warren 37185  37185       93   968     4
10 0.124     1.428  1837    1837      Stokes 37169  37169       85  1612     1
   NWBIR74 BIR79 SID79 NWBIR79                       geometry
1       10  1364     0      19 MULTIPOLYGON (((-81.47276 3...
2       10   542     3      12 MULTIPOLYGON (((-81.23989 3...
3      208  3616     6     260 MULTIPOLYGON (((-80.45634 3...
4      123   830     2     145 MULTIPOLYGON (((-76.00897 3...
5     1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3...
6      954  1838     5    1237 MULTIPOLYGON (((-76.74506 3...
7      115   350     2     139 MULTIPOLYGON (((-76.00897 3...
8      254   594     2     371 MULTIPOLYGON (((-76.56251 3...
9      748  1190     2     844 MULTIPOLYGON (((-78.30876 3...
10     160  2038     5     176 MULTIPOLYGON (((-80.02567 3...

>class(nc_lst[[1]]
[1] "sf"         "data.frame"
>class(b3[[1]]$head_sf)
[1] "sf"         "data.frame"

Dang,不知道为什么 getOption('sf_max_print', default = 6) 不限制为 6。 dplyer 已经控制了引用/取消引用,但我还没有解决这个问题。到目前为止,这些都是我不好的建议。

另外,来自tidyverseWhat Hadley suggests,拿着哈德利的换头和打印,

glimpse_head2 <- function(x, n = 6) {
head(print(x, n))
invisible(x)
} 

虽然这不会变得暗淡,但似乎比我上面的要简单得多,并提供所需的 bbox 值。并且仍然不限于 6,因为 sfg 的 head 方法被硬编码为 10L:

> getS3method('head', 'sfg')
function (x, n = 10L, ...) 
{
    structure(head(unclass(x), n = n, ...), class = class(x))
}
<bytecode: 0x5646a6a38228>
<environment: namespace:sf>

【讨论】:

  • 您的编辑很有趣,虽然它没有像您的解决方案那样完全解决问题
  • 同意,被 10L 困扰了,所以虽然 sfg 有一个 head 方法,但它没有被导出,严格来说这是我理解的含义。