Вопрос по r – Как написать в буфер обмена на Ubuntu / Linux в R?
Я использую Ubuntu 11.10, и я хотел бы иметь возможность записи в буфер обмена (или основной выбор). Следующее дает ошибку
> x <- 1:10
> dput(x, 'clipboard')
Error in file(file, "wt") : 'mode' for the clipboard must be 'r' on Unix
How can I write to the clipboard/primary selection?
Обратите внимание, что я виделэтот старый пост R-Help, но я до сих пор не понимаю, что мне делать.
Linux does not have a clipboard but an X11 session has primary and secondary selections. ?file says
Clipboard:
'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")'.
so RTFM applied. Writing to an X11 selection needs multiple threads and I did not think it worth the very considerable effort of implementing (unlike for Windows).
Note that window managers may have other clipboards, and for example the RGtk2 package has interfaces to gtk clipboards.
Я не мог заставить другие решения работать, поэтому я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.
Reading from the clipboardЧтение одинаково сложно. Здесь сопутствующая функция для вышеупомянутого.
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))
})
}
}
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. Однако вам не нужно сначала запускать его отдельно.
best Кстати, но вот как я мог заставить его работать:
Install xclip:sudo apt-get install xclip
Read the manual: man xclip
Write to X11 primary in R: write.table(1:10, pipe("xclip -i", "w"))
Update:
Обратите внимание, что объект передан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, ...)
}