【问题标题】:Suppress large output to R console抑制大输出到 R 控制台
【发布时间】:2014-06-23 19:03:54
【问题描述】:

如何让 R 检查对象是否太大而无法在控制台中打印?这里的“太大”是指大于用户定义的值。

示例:您有一个列表 f_data,其中包含两个元素 f_data$data(一个 100MB 的数据帧)和 f_data$info(例如,一个向量)。假设您要检查f_data$data data.frame 的前几个条目,但您犯了一个错误并键入head(f_data) 而不是head(f_data$data)。 R 将尝试将f_data 的全部内容打印到控制台(这将花费很长时间)。 是否可以设置一个选项来抑制大于 1MB 的对象的输出?

编辑:谢谢你们的帮助。在实现max.rows 选项后,我意识到这确实提供了所需的输出。但是输出需要很长时间才能显示的问题仍然存在。下面我给你举个恰当的例子。

df_nrow=100000
df_ncol=100
#create list with first element being a large data.frame
#second element is a short vector
test_list=list(df=data.frame(matrix(rnorm(df_nrow*df_ncol),nrow=df_nrow,ncol=df_ncol)),
               vec=1:110)

#only print the first 100 elements of an object
options(max.print=100)

#head correctly displays the first row of the data.frame
#BUT for some reason the output takes really long to show up in the console (~30sec)
head(test_list)
#let's try to see how long exactly
system.time(head(test_list))
#   user  system elapsed 
#      0       0       0
#well, obviously system.time is not the proper tool to measure this

#the same problem if I just print the object to the console without using head
test_list$df

我假设 R 对正在打印的对象执行某种分析,这需要很长时间。

编辑 2: 根据我下面的评论,我检查了如果我使用 matrix 而不是 data.frame,问题是否仍然存在。

#create list with first element being a large MATRIX
test_list=list(mat=matrix(rnorm(df_nrow*df_ncol),nrow=df_nrow,ncol=df_ncol),vec=1:110)

#no problem
head(test_list)

#no problem
test_list$mat

难道是data.frame 对象的控制台输出没有真正有效地实现?

【问题讨论】:

  • 我一般设置options(max.print)来防止控制台溢出。不过,这会限制打印字符的数量,而不是大小。
  • @RomanLuštrik 我相信它实际上限制了“元素”的打印,这大约是 data.frame 的行和列表的条目。
  • 啊,对不起。这就是我的意思,元素。感谢您的更正。我刚刚检查过,一个元素将是 data.frame 中的一个数字。我有一个包含 40 个变量的 data.frame,并将打印限制为 500。它只显示 12 行(12 * 40 = 480)。
  • 谢谢你们。请看我上面的编辑。
  • 我现在看到,如果我将 data.frame 替换为 matrix,则不会出现此问题。也许这与data.frames 的存储方式有关。据我所知,它们是一个向量列表,每个向量都是data.frame 的一列。由于max.print适用于行,R不能简单地遍历data.frame的元素...

标签: r console output


【解决方案1】:

我认为没有这样的选项,但是您可以使用object.size 检查对象的大小,如果低于阈值(以字节为单位),则打印它,例如:

print.small.objects <- function(x, threshold = 1e06, ...)
{
  if (object.size(x) < threshold) {
    print(x, ...)
  } else {
    cat(paste("too big object\n"))
    print(object.size(x))
  }
}

【讨论】:

  • 谢谢!那会奏效。但是,通常我只是将对象打印到控制台而不使用headprint 或任何其他功能。如果碰巧我忘记它是一个非常大的对象,我正在尝试打印到控制台,我的问题编辑中描述的问题仍然存在。
  • showDefault 可能是您要修改的功能。我认为这就是当您输入对象名称并按回车键时打印对象的功能。您可以查看方法包中的函数 showDefault(或在 R 提示符下键入 showDefault)。或者,您可以定义一个 S3 类来存储您的 matrixdata.frame 对象并为该类创建一个 show 方法。
【解决方案2】:

这是一个示例,您可以将其调整到 100MB。如果对象的大小超过 8e5 字节,它基本上只打印前 6 行和 5 列。你也可以把它变成一个函数并将它放在你的.Rprofile

> lst <- list(data.frame(replicate(100, rnorm(1000))), 1:10)
> sapply(lst, object.size)
# [1] 810968     88
> lapply(lst, function(x){
      if(object.size(x) > 8e5) head(x)[1:5] else x
  })
#[[1]]
#          X1         X2          X3          X4         X5
#1  0.3398235 -1.7290077 -0.35367971  0.09874918 -0.8562069
#2  0.2318548 -0.3415523 -0.38346083 -0.08333569 -1.1091982
#3  0.0714407 -1.4561768  0.50131914 -0.54899188  0.1652095
#4 -0.5170228  1.7343073 -0.05602883  0.87855313  0.4025590
#5  0.6962212 -0.3179930  0.28016057  1.05414456 -0.5172885
#6  0.9471200  1.4424843 -1.46323827 -0.78004192 -1.3611820
#
#[[2]]
# [1]  1  2  3  4  5  6  7  8  9 10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    相关资源
    最近更新 更多