Search code examples
runixclipboardtransfer

How can I read data from the clipboard into R on a Unix system?


I want to move data from a web site into R by simply copying it, and then in R use the scan command. But I need to do this operating system independent. I know that on Windows I can simply use scan("clipboard") and on MacOS scan(pipe("pbpaste")). But whatever I try on Unix I get an error "No protocol specified".

I found some discussions on this online. Among others, it was suggested that the commands

scan(file(description='clipboard'))
read.delim("X11_clipboard")
read.table(pipe("xclip -selection clipboard -o",open="r"))

might work, but neither do for me.

I am using Linux CentOS 7.


Solution

  • If you look at other StackOverflow questions such as this one, you see xclip suggested as well as two handy aliases

    alias setclip="xclip -selection c"
    alias getclip="xclip -selection c -o"
    

    which give a strong hint as to how this works. To test, I installed xclip (which is available for Ubuntu which I run), highlighted three lines from the R start up text and tried it:

    edd@rob:~$ xclip -selection c -o
    R version 4.0.3 (2020-10-10) -- "Bunny-Wunnies Freak Out"
    Copyright (C) 2020 The R Foundation for Statistical Computing
    Platform: x86_64-pc-linux-gnu (64-bit)
    
    R is free software and comes with ABSOLUTELY NO WARRANTY.
    You are welcome to redistribute it under certain conditions.
    Type 'license()' or 'licence()' for distribution details.
    
      Natural language support but running in an English locale
    
    R is a collaborative project with many contributors.
    Type 'contributors()' for more information and
    'citation()' on how to cite R or R packages in publications.
    
    Type 'demo()' for some demos, 'help()' for on-line help, or
    'help.start()' for an HTML browser interface to help.
    Type 'q()' to quit R.
    
    edd@rob:~$ 
    

    Works as advertised: xclip recovers the clipboard content, and prints it to stdout.

    To use this in R, we simply need to read from that output which we can via the pipe() connection:

    > res <- readLines(pipe("xclip -selection c -o"))
    > str(res)
     chr [1:19] "" ...
    > res[1:3]
    [1] ""                                                             
    [2] "R version 4.0.3 (2020-10-10) -- \"Bunny-Wunnies Freak Out\""  
    [3] "Copyright (C) 2020 The R Foundation for Statistical Computing"
    > 
    

    But even that is overkill. Looking at ??clipboard suggests help(connections) which has an entire paragraph (!!) about this which includes

     ‘file’ can be used with ‘description = "clipboard"’ in mode ‘"r"’
     only.  This reads the X11 primary selection (see <URL:
     https://specifications.freedesktop.org/clipboards-spec/clipboards-latest.txt>),
     which can also be specified as ‘"X11_primary"’ and the secondary
     selection as ‘"X11_secondary"’.  On most systems the clipboard
     selection (that used by ‘Copy’ from an ‘Edit’ menu) can be
     specified as ‘"X11_clipboard"’.
    

    and indeed:

    > res2 <- readLines(file(description="clipboard"))
    Warning message:
    In readLines(file(description = "clipboard")) :
      incomplete final line found on 'clipboard'
    > str(res2)
     chr [1:19] "" ...
    > res2[1:3]
    [1] ""
    [2] "R version 4.0.3 (2020-10-10) -- \"Bunny-Wunnies Freak Out\""  
    [3] "Copyright (C) 2020 The R Foundation for Statistical Computing"  
    > 
    

    Seemingly, you would still need xclip to write to the clipboard from R.