强制rstudio使用浏览器而不是查看器

raw*_*awr 15 r rstudio

考虑(如果rstudio)将在浏览器中打开某些内容的功能,如果y = TRUE在浏览器中和浏览器中y = FALSE.您可以强制whatever在浏览器中打开options(viewer = NULL)(然后需要重置为之前),但我无法使用常规on.exit方法在函数内部使用它.在Windows和osx上测试.

f <- function(x, y = TRUE) {
  if (y) {
    oo <- getOption('viewer')
    on.exit(options(viewer = oo))
    options(viewer = NULL)
  } else options(viewer = NULL)
  print(getOption('viewer'))
  DT::datatable(x)
}

g <- function(x, y = TRUE) {
  if (y) {
    oo <- getOption('viewer')
    on.exit(options(viewer = oo))
    options(viewer = NULL)
  } else options(viewer = NULL)
  print(getOption('viewer'))
  htmlTable::htmlTable(x)
}

## in rstudio, returns the viewer function
getOption('viewer')
# function (url, height = NULL) 
# ...

## opens in viewer despite `options(viewer = NULL)`
g(mtcars)
# NULL

## again returns the function, ie, reset my options to before g call successfully
getOption('viewer')
# function (url, height = NULL) 
# ...

## opens in browser but leaves `options(viewer = NULL)` after exiting
g(mtcars, FALSE)
# NULL

getOption('viewer')
# NULL
Run Code Online (Sandbox Code Playgroud)

看起来观众不会在功能环境中尊重我的选项,只需要一些html(g)或widget(f).我认为两者都会viewer = NULL在函数内部使用,并以退出时的方式返回我的选项,以便我可以控制我想要查看结果的位置.

或者有没有更好的方法来为html和小部件执行此操作?我试过这个options论点DT::datatable无济于事,但这对htmlTable::htmlTable案件没有帮助.

我能想到的唯一另一种方法是将所有代码写入临时文件并使用if (rstudio) rstudio::viewer(tempfile) else browseURL(tempfile)我认为对于看似如此简单的事情而言需要做的很多工作.

Kev*_*hey 9

虽然这不是一个解决方案,但我认为它说明了正在发生的事情.尝试Sys.sleep()on.exit()处理程序中添加一个调用:

f <- function(x) {
  viewer <- getOption("viewer")
  on.exit({
    print("Restoring viewer...")
    Sys.sleep(3)
    options(viewer = viewer)
  }, add = TRUE)
  options(viewer = NULL)
  DT::datatable(x)
}

## opens in viewer despite `options(viewer = NULL)`
f(mtcars)
Run Code Online (Sandbox Code Playgroud)

您会注意到RStudio 在处理程序执行完毕之后才"决定"如何处理DT::datatable()调用结果.这意味着,当RStudio想要弄清楚结果时,观众已经恢复了!可能性是,RStudio等待直到R不再"忙"来决定如何显示结果内容,然后对于选项的临时更改来说太迟了.on.exit()viewer

请注意,这并不能解释htmlTable行为.我最好的猜测是存在某种竞争条件; 失败的viewer选择似乎随着战略性的Sys.sleep()呼叫而消失......

不幸的是,解决这个问题意味着避免使用on.exit()呼叫 - 当然,除非我们能够在RStudio中解决这个问题.


raw*_*awr 5

这是通过将代码写入临时文件并使用browseURL或任何您喜欢的方式来获得此功能的一种方法.

双方的主旨fg是相同的,所以你可以有一个函数来处理任何类型的HTML代码或控件,我想.可能小部件需要selfcontained = TRUE.

f <- function(x, y = TRUE) {
  x <- if ((inherits(x, 'iplot'))) x else DT::datatable(x)
  if (!y) {
    htmlFile <- tempfile(fileext = '.html')
    htmlwidgets::saveWidget(x, htmlFile, selfcontained = TRUE)
    utils::browseURL(htmlFile)
  } else x
}

g <- function(x, y = TRUE) {
  x <- htmlTable::htmlTable(x)
  if (!y) {
    htmlFile <- tempfile(fileext = '.html')
    writeLines(x, con = htmlFile)
    utils::browseURL(htmlFile)
  } else x
}

## opens in viewer
g(mtcars)
## opens in browser
g(mtcars, FALSE)

## same for widgets
f(mtcars)
f(mtcars, FALSE)

f(qtlcharts::iplot(1:5, 1:5), FALSE)

## and my options haven't changed
getOption('viewer')
# function (url, height = NULL) 
# ...
Run Code Online (Sandbox Code Playgroud)

请注意,这实际上是htmlTable::htmlTable使用不同查看器的正确方法,但g应该适用于任何html.

library('htmlTable')
print(htmlTable(mtcars), useViewer = utils::browseURL)
Run Code Online (Sandbox Code Playgroud)