如何在R中的Ubuntu / Linux上写入剪贴板?

时间:2012-06-09 08:29:28

标签: r

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

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

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

请注意,我已经看过this old R-Help post,但我仍然不清楚我应该做些什么。

  

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 个答案:

答案 0 :(得分:19)

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。不过,您不需要先单独启动它。

答案 1 :(得分:13)

不确定这是否是最佳方式,但这是我可以让它工作的方式:

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

    <强>更新

    请注意,传递给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, ...)
    }
    

答案 2 :(得分:2)

cliper程序包使此操作非常简单

x <- 1:10
clipr::write_clip(x)

答案 3 :(得分:1)

版本:

  • 薄荷18.1,肉桂
  • xclip 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")
      })
    }
}

它是my personal R package中函数的淡化版本。

从剪贴板中读取

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

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))
    })
  }
}