39

我正在运行 Ubuntu 11.10,我希望能够写入剪贴板(或主要选择)。以下给出错误

> x <- 1:10
> dput(x, 'clipboard')
Error in file(file, "wt") : 'mode' for the clipboard must be 'r' on Unix

如何写入剪贴板/主要选择?

请注意,我已经看过这个旧的 R-Help 帖子,但我仍然不清楚我应该做什么。

Linux 没有剪贴板,但 X11 会话有主要和次要选择。? 文件说

剪贴板:

  'file' can also be used with 'description = "clipboard"' in mode
  '"r"' only.  It reads the X11 primary selection, which can also be
  specified as '"X11_primary"' and the secondary selection as
  '"X11_secondary"'.

  When the clipboard is opened for reading, the contents are
  immediately copied to internal storage in the connection.

  Unix users wishing to _write_ to the primary selection may be able
  to do so via 'xclip' (<URL:
  http://people.debian.org/~kims/xclip/>), for example by
  'pipe("xclip -i", "w")'.

所以应用了RTFM。写入 X11 选择需要多个线程,我认为不值得付出相当大的努力来实现(与 Windows 不同)。

请注意,窗口管理器可能有其他剪贴板,例如 RGtk2 包具有到 gtk 剪贴板的接口。

4

4 回答 4

22
clipboard <- function(x, sep="\t", row.names=FALSE, col.names=TRUE){
     con <- pipe("xclip -selection clipboard -i", open="w")
     write.table(x, con, sep=sep, row.names=row.names, col.names=col.names)
     close(con)
}

vec <- c(1,2,3,4)

clipboard(vec)
clipboard(vec, ",", col.names=FALSE)
clipboard(vec, " ", row.names=TRUE)

在创建函数后,您可以将写入的任何内容粘贴回剪贴板。默认返回带有列但没有行名的制表符分隔值。如图所示,根据您的喜好指定其他分隔符、包括行名或排除列名。

编辑:为了澄清,您仍然需要安装 xclip。不过,您不需要先单独启动它。

于 2014-01-09T20:49:47.150 回答
19

Clipr 包让这变得非常简单

x <- 1:10
clipr::write_clip(x)
于 2018-11-17T03:00:51.880 回答
18

不确定这是否是最好的方法,但这是我如何让它工作的方法:

  1. 安装 xclip:sudo apt-get install xclip
  2. 阅读手册:man xclip
  3. 写入 R 中的 X11 主节点:write.table(1:10, pipe("xclip -i", "w"))

更新:

请注意,write.table在管道关闭之前,传递给的对象不会出现在剪贴板中。您可以通过调用强制关闭管道gc()。例如:

write.table(1:10, pipe("xclip -i", "w"))  # data may not be in clipboard
gc()                                      # data written to primary clipboard

管理连接的更好方法是使用带有 的函数on.exit(close(con)),即使write.table调用抛出错误,它也会关闭管道。请注意,您需要确保根据您的系统设置写入您打算使用的剪贴板(主要是默认设置)。

write.xclip <- function(x, selection=c("primary", "secondary", "clipboard"), ...) {
  if (!isTRUE(file.exists(Sys.which("xclip")[1L])))
    stop("Cannot find xclip")
  selection <- match.arg(selection)[1L]
  con <- pipe(paste0("xclip -i -selection ", selection), "w")
  on.exit(close(con))
  write.table(x, con, ...)
}
于 2012-06-09T11:11:12.190 回答
2

版本:

  • 薄荷 18.1,肉桂
  • 剪辑 0.12
  • R 3.4.0 (2017-04-21)

我无法让其他解决方案发挥作用,所以我man接受了。这种方法对我有用(基于其他人的解决方案)。

write_clipboard = function(x, .rownames = F) {
    #decide how to write
    #windows is easy!
    if (Sys.info()['sysname'] %in% c("Windows")) {
      #just write as normal
      write.table(x, "clipboard", sep = "\t", na = "", row.names = F)
    } else {
      #for non-windows, try xclip approach
      #https://stackoverflow.com/a/10960498/3980197
      write.xclip = function(x) {
        #if xclip not installed
        if (!isTRUE(file.exists(Sys.which("xclip")[1L]))) {
          stop("Cannot find xclip")
        }
        con <- pipe("xclip -selection c", "w")
        on.exit(close(con))
        write.table(x, con, sep = "\t", na = "", row.names = F)
      }

      tryCatch({
        write.xclip(x)
      }, error = function(e) {
        message("Could not write using xclip")
      })
    }
}

这是我个人 R 包中函数的淡化版本。

从剪贴板读取

阅读同样困难。这是上述内容的配套功能。

read_clipboard = function(header = T,
                          sep = "\t",
                          na.strings = c("", "NA"),
                          check.names = T,
                          stringsAsFactors = F,
                          dec = ".",
                          ...) {
  #decide how to read
  #windows is easy!
  if (Sys.info()['sysname'] %in% c("Windows")) {
    #just read as normal
    read.table(file = con, sep = sep, header = header, check.names = check.names, na.strings = na.strings, stringsAsFactors = stringsAsFactors, dec = dec, ...)
  } else {
    #for non-windows, try xclip approach
    #https://stackoverflow.com/a/10960498/3980197
    read.xclip = function(x) {
      #if xclip not installed
      if (!isTRUE(file.exists(Sys.which("xclip")[1L]))) {
        stop("Cannot find xclip")
      }
      con <- pipe("xclip -o -selection c", "r")
      on.exit(close(con))
      read.table(file = con, sep = sep, header = header, check.names = check.names, na.strings = na.strings, stringsAsFactors = stringsAsFactors, dec = dec, ...)
    }

    tryCatch({
      read.xclip(x)
    }, error = function(e) {
      message(sprintf("error: %s", e$message))
    })
  }
}
于 2017-06-24T23:54:05.053 回答