【问题标题】:Quickly view an R data.frame, vector, or data.table in Excel在 Excel 中快速查看 R data.frame、vector 或 data.table
【发布时间】:2012-08-23 07:03:03
【问题描述】:

如何在 Excel 中快速打开小型 R 表/矢量对象?

例如,假设您有以下三个要在 Excel 中查看的对象:

## A data frame with commas and quotes
df = data.frame(
  area = unname(state.x77[,'Area']),
  frost = unname(state.x77[,'Frost']),
  comments = "Ok for a visit, but don't want to live there",
  challengeComments = c('"', '""'))
row.names(df) = state.name
df = df[1:10, ]
df['California', 'comments'] = "Would like to live here"

## A Matrix
mat = matrix(rnorm(100), 10)

## A Vector
v = 1:10

【问题讨论】:

  • 我写了问题和答案作为参考。我不确定回答自己的问题是否会让我以自我为中心或无私。
  • 如果您只想在电子表格中查看数据而不是打开 Excel,您可以使用 fixeditdata.entry
  • 好电话。我以为有类似 View 的东西,但尝试了 view 并没有考虑大写它。
  • @Dason : 使用 ??viewutils::View 会出现。
  • @geneorama - 以自我为中心或无私,它实际上是在 stackoverflow 上推广的!有关详细信息,请参阅this blog。干得好,看起来很有用!

标签: r dataframe data.table


【解决方案1】:

我写了这个函数来完成这个任务。我称之为“写临时文件”或“wtf”。如果您有与 Excel 关联的 csv 文件,它仅适用于 Windows。

您可以查看 PBSmodelling::openFile 中的代码,了解如何将其应用于不同的操作系统。

wtf = function (x) {
  tempFilePath = paste(tempfile(), ".csv")
  tempPath = dirname(tempFilePath)
  preferredFile = paste(deparse(substitute(x)), ".csv", sep = "")
  preferredFilePath = file.path(tempPath, preferredFile)

  if(length(dim(x))>2){
    stop('Too many dimensions')
  }
  if(is.null(dim(x))){
    x = as.data.frame(x)
  }
  if (is.null(rownames(x))) {
    tmp = 1:nrow(x)
  }else {
    tmp = rownames(x)
  }
  rownames(x) = NULL
  x = data.frame(RowLabels = tmp, x)
  WriteAttempt = try(
    write.table(x, file=preferredFilePath, quote=TRUE, sep=",", na="",
                row.names=FALSE, qmethod="double"),
    silent = TRUE)
  if ("try-error" %in% class(WriteAttempt)) {
    write.table(x, file=tempFilePath, , quote=TRUE, sep=",", na="",
                row.names=FALSE, qmethod="double")
    shell.exec(tempFilePath)
  } else {
    shell.exec(preferredFilePath)
  }
}


wtf(df)
wtf(mat)
wtf(v)

如果你多次打开同一个对象,由于错误处理,它仍然可以工作,但它会有一个混乱的临时名称。

wtf(df)
df$MoreData = pi
wtf(df)

【讨论】:

  • 您是否在 Windows 以外的操作系统上对此进行了测试?另外:根据哪个 WindowsOS 和哪个版本的 Excel,这可能会启动 Excel 应用程序的多个实例,而不是在一个 Excel 实例的多个窗口中打开 .csv 文件。这不是你的错(这是 Redmond 的错),但我敢打赌,有一些巧妙的系统调用可以解决这些问题。
  • "openFile" 来自 PBSmodelling 有一些聪明的方法来测试你正在使用的操作系统。我认为对 R-Excel 链接的需求主要是 Windows 用户想要的。
  • @lselzer 谢谢。最初的名称是“writeTemp”,但当我开始每天使用它数百次时,我将它缩短为“wt”。新的和改进的版本需要一个新的名字......“wtf”是很自然的。
  • 这个函数的名字是自我描述的,当你真的需要回答 WTF 正在处理你的 data.frame 时。
  • @CaffeineConnoisseur 我等了 1,562 天才收到这条评论
【解决方案2】:

使用write.csv(x, "clipboard")并粘贴到excel中。

【讨论】:

  • 在尝试之前我很喜欢这个想法。不幸的是,它将整行粘贴到每行的第一个单元格中。它不会自动将每个值放在自己的单元格中。
  • 我必须使用“文本到列”进行第一次粘贴,并设置正确的分隔符。之后,它对我来说很好(Excel 2007)。后续粘贴这里不需要“文本到列”。
  • 对我有用,虽然我使用 OOo Calc。
【解决方案3】:

对不起无耻广告...你可以试试我的包http://cran.r-project.org/web/packages/excel.link/index.html 它看起来像:

library(excel.link)
xlrc[a1]=df

它依赖于 Omegahat RDCOMClient 包,因此需要从源代码安装它:

install.packages("RDCOMClient", repos = "http://www.omegahat.org/R")
install.packages("excel.link", repos = "http://cran.at.r-project.org",type="source")

【讨论】:

    【解决方案4】:

    我编写了一个在 Libre Office Calc 或 Excel 中打开文件的函数。 See here for details.

    view <- function(data, autofilter=TRUE) {
        # data: data frame
        # autofilter: whether to apply a filter to make sorting and filtering easier
        open_command <- switch(Sys.info()[['sysname']],
                               Windows= 'open',
                               Linux  = 'xdg-open',
                               Darwin = 'open')
        require(XLConnect)
        temp_file <- paste0(tempfile(), '.xlsx')
        wb <- loadWorkbook(temp_file, create = TRUE)
        createSheet(wb, name = "temp")
        writeWorksheet(wb, data, sheet = "temp", startRow = 1, startCol = 1)
        if (autofilter) setAutoFilter(wb, 'temp', aref('A1', dim(data)))
        saveWorkbook(wb, )
        system(paste(open_command, temp_file))
    }
    

    【讨论】:

    • 我对这个非常方便的函数有两个修复,一个使它能够处理 dplyr-datasets,另一个指定要在这个函数中使用的 XLConnect 函数应该来自 XLConnect 包,通过使用“::”-操作符。这是因为我遇到了冲突包的问题。如果您对此功能有疑问,请检查 Jeromy 提供的链接中的 cmets-field。
    【解决方案5】:

    我经常使用它来将数据表粘贴到 Excel 中:

    write.table(x, "clipboard", row.names=F, sep='\t')
    

    要将(子)表格从 Excel 复制到 R,请执行以下操作(假设表格有标题行):

    read.csv('clipboard', sep='\t')
    

    【讨论】:

    【解决方案6】:

    我为 windows 编写了一个函数。但它可能也适用于其他操作系统。

    它在 C:\Users\...\Documents\Rview 中创建临时文件,并使用 browseURL() 打开它们。您最多可以同时打开 99 个文件。您可以通过参数“名称”轻松选择应显示的暗名称。该函数会在 col/rownames 中的 +,-,= 之前添加 ',以便在 Excel 中正确显示。

    我个人更喜欢使用 Sys.getenv("TMP") 的解决方案,而不是使用 tempfile(),因为 tempfile() 会在一段时间后弄乱您的临时文件夹。

    有关详细信息,请参阅代码顶部的参数说明。

    # This function creates a CSV file from a data.frame/matrix and opens it with the default CSV-opening-program
    # of the computer.
    #
    # x = data.frame/matrix
    # names = dimnames to be saved in the file. "col"=colnames, "rowcol"=rownames&colnames, "row"=rownames, "no"=no dimnames
    # nrows = maximum number of rows    to be saved (for higher speed with large datasets)
    #         if n=-1, all rows will be displayed.-> see also the help for read.table()
    # ncols = maximum number of columns to be saved (for higher speed with large datasets)
    # folder = directory, where the temporary file should be saved.
    #          If NULL an accessible folder in C:/Users/.../Documents will be created automatically.
    # quote = should quotes be written into the csv File? -> see also the help for write.table()
    # na = how should NA values be displayed in the csv File? -> see also the help for write.table()
    # openfolder = Should the folder with all temporary files be opened after having created the file?
    
    view <- function(x, names=c("col","rowcol","row","no"), nrows=10000, ncols=1000, folder=NULL, quote=FALSE, na="NA", openfolder=FALSE, ...){
    
      names <- match.arg(names)
      if(is.null(dim(x))) {
        x <- as.matrix(x)
      }
      if(is.null(colnames(x))) colnames(x) <- paste0("V",1:ncol(x))
    
      if(nrows<0) nrows <- nrow(x)
      if(ncols<0) ncols <- ncol(x)
      # Shrink data.frame such that it can be saved & viewed faster.
      nrows <- min(nrow(x), nrows)
      if(nrows!=nrow(x)) x <- x[1:nrows,,drop=FALSE]
      ncols <- min(ncol(x), ncols)
      if(ncols!=ncol(x)) x <- x[,1:ncols,drop=FALSE]
    
    
      # Define paths
      # If is.null(folder), wird ein temporaerer Ordner im Windows-Dateisystem angelegt.
      if(is.null(folder)) {
        folder <- paste0(Sys.getenv("TMP"), "\\Rview")
        suppressWarnings( dir.create(folder) )
      }  
    
      # Wenn am Schluss des Pfades kein "/" angefuegt wurde, wird dies gemacht:
      if( !substr(folder,nchar(folder),nchar(folder))%in%c("/","\\") ) folder <- paste0(folder, "\\")
      pfad0 <- folder
      name <- "Rview_tmp"
      nr <- "01"
      csv <- ".csv"
    
      # Check if there are existing files in the folder
      fil <- list.files(pfad0)
      # If there are no files in the folder, use the default save path.
      if(length(fil)==0){
        pfad1 <- paste0(pfad0, name, nr, csv)
      } else {
        # Remove all files in the folder (if possible)
        fil <- paste0(pfad0, fil)
        suppressWarnings( try( file.remove( fil )  , silent=TRUE) )
        fil <- list.files(pfad0)
        # If there are no files anymore use the default save path.
        if( length(fil)==0 ) {
          pfad1 <- paste0(pfad0, name, nr, csv)
        } else {
          # If there are sill files, read out the number of the newest file (with the highest number)
          ncharfil <- nchar(fil)
          mx <- max( as.numeric( substr(fil,ncharfil-5,ncharfil-4) ) )
          # Add 1 to the number of the file
          mxpl1 <- as.character( mx+1 )
          if(nchar(mxpl1)==1) mxpl1 <- paste0("0",mxpl1)
          # Create a new path
          pfad1 <- paste0(pfad0, name, mxpl1, csv)
        }
      }
    
      # Rownames und colnames, die mit +, - oder = anfangen, mit ' am Anfang versehen, dass es von Excel richtig dargestellt wird
      rn1 <- rownames(x)
      cn1 <- colnames(x)
      ind <- substr(rn1,1,1)%in%c("+","-","=")
      if(any(ind)) rownames(x)[ind] <- paste0(" ",rn1[ind])
      ind <- substr(cn1,1,1)%in%c("+","-","=")
      if(any(ind)) colnames(x)[ind] <- paste0(" ",cn1[ind])
    
      # Write CSV file & open.
      if(names=="row") {
        # If the first cell of the file is named "ID" Microsoft Excel warns that a SYLK file is opened. Therefore it is renamed.
        if(rownames(x)[1]=="ID") rownames(x)[1] <- "lD"
        write.table(x, file=pfad1, sep = ";", col.names=FALSE, row.names=TRUE, quote=quote, na=na, ...)
      } else if (names=="col") {
        # If the first cell of the file is named "ID" Microsoft Excel warns that a SYLK file is opened. Therefore it is renamed.
        if(colnames(x)[1]=="ID") colnames(x)[1] <- "lD"
        write.table(x, file=pfad1, sep = ";", col.names=TRUE, row.names=FALSE, quote=quote, na=na, ...)
      } else if (names=="rowcol") {
        write.table(x, file=pfad1, sep = ";", col.names=NA)                    # Colnames & Rownames
      } else {
        write.table(x, file=pfad1, sep = ";", col.names=FALSE, row.names=FALSE, quote=quote, na=na, ...)
      }
    
      browseURL(pfad1)
      if(openfolder) {
        Sys.sleep(1)
        browseURL(folder)
      }
    }
    

    【讨论】:

      【解决方案7】:

      geneorama 的解决方案很棒,但是使用write.table 会很慢。您可以将其从 data.table package 更改为 fwrite

      这个解决方案有用的主要原因(至少对我来说)是因为View可怕的大型数据框。我用 15600 obs 的数据框测试了geneorama 的解决方案。通过 1270 个变量,它在 16 秒后打开。使用fwrite 版本时,它会在 0.6 秒后打开!

      这是修改后的函数:

      wtf = function (x) {
        tempFilePath = paste(tempfile(), ".csv")
        tempPath = dirname(tempFilePath)
        preferredFile = paste(deparse(substitute(x)), ".csv", sep = "")
        preferredFilePath = file.path(tempPath, preferredFile)
      
        if(length(dim(x))>2){
          stop('Too many dimensions')
        }
        if(is.null(dim(x))){
          x = as.data.frame(x)
        }
        if (is.null(rownames(x))) {
          tmp = 1:nrow(x)
        }else {
          tmp = rownames(x)
        }
        rownames(x) = NULL
        x = data.frame(RowLabels = tmp, x)
        WriteAttempt = try(
          data.table::fwrite(x, file=preferredFilePath, quote=TRUE),
          silent = TRUE)
        if ("try-error" %in% class(WriteAttempt)) {
          data.table::fwrite(x, file=tempFilePath, quote=TRUE)
          shell.exec(tempFilePath)
        } else {
          shell.exec(preferredFilePath)
        }
      }
      

      【讨论】:

      • 没错,但@geneorama 在他写的时候没有fwrite 可用!我应该重写我的函数,也许我会。
      【解决方案8】:

      不完全回答这个问题,因为这不仅限于 Excel,但这里有一个简单的函数(受其他一些答案的启发),它从一个对象创建一个临时 csv 文件并将其路径复制到剪贴板(使用包clipr)。

      这允许在任何应用程序(例如sc-im、Libreoffice calc、Excel、Gnumeric 等)中快速可视化对象,只需键入所选应用程序的名称并在命令行中粘贴剪贴板的内容即可。

      ext <- function(data) {
          file_name <- tempfile(fileext = ".csv")
          file <- write.csv(data, file_name)
          clipr::write_clip(paste(file_name))
      }
      

      我最初使用这个是因为我很难让sc-imsystem() 从 R 中打开一个文件,但最后,我发现能够选择我想要使用的应用程序非常方便可视化临时文件:根据我想要探索的对象,一个或另一个应用程序可能更合适。

      【讨论】:

        【解决方案9】:

        我想要一些模仿 View() 的东西,但在 Excel 中,而不是在 RStudio 的内部视图中。 从上面的许多帖子中学到了一点点。最终得到了一段非常简单的代码......到目前为止......似乎对我有用。
        只是想快速查看它,但在 Excel 中。如果我决定要保存文件,我可以在 Excel 中处理。否则,它只会在 R 会话的默认临时目录中自动创建一个临时文件。它被设置为默认对 R 会话的 .Last.value 进行操作,或者您输入一个可以强制转换为数据的对象框架

        我只是在我的 R 配置文件中定义了它,因此它始终可用。 将其命名为“查看外部”的 ViewExt 可能更有意义,以免将其直接链接到 Excel,而是用户在 Windows 中设置的任何选择程序作为 .csv 文件的默认编辑器。但这就是我使用的所以这就是我命名它

            ViewExcel <- function(df = .Last.value, file = tempfile(fileext = ".csv")) {
               df <- try(as.data.frame(df))
               stopifnot(is.data.frame(df))
               utils::write.csv(df, file = file)
               base::shell.exec(file)
            }
        
            #Examples
            mtcars
            ViewExcel()
            mtcars %>% ViewExcel()
            ViewExcel(mtcars)
        

        【讨论】:

          【解决方案10】:

          使用 viewxl 包中的 view_in_xl 函数。这相当于在 RStudio 中使用 F4 键盘快捷键。

          viewxl:::view_in_xl(x)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-07-03
            • 1970-01-01
            • 2018-12-18
            • 2020-08-11
            • 2021-09-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多