【问题标题】:Importing data into R from google spreadsheet从谷歌电子表格将数据导入R
【发布时间】:2014-05-17 09:42:58
【问题描述】:

Google 电子表格发布选项似乎发生了变化。不再能够以 csv 或选项卡文件 (see this recent post) 的形式发布到 Web。因此,使用 RCurl 从谷歌电子表格将数据导入 R 的常用方法不再起作用:

require(RCurl)
u <- "https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AmFzIcfgCzGFdHQ0eEU0MWZWV200RjgtTXVMY1NoQVE&single=true&gid=4&output=csv"
tc <- getURL(u, ssl.verifypeer=FALSE)
net <- read.csv(textConnection(tc))

有人有解决办法吗?

【问题讨论】:

  • 如果您分享您认为“常规方式”的内容,可能会有所帮助。此外,我似乎仍然可以使用 Google 电子表格以 CSV 格式发布到网络。
  • gspreadr:一个用于从 R 访问和管理 Google 电子表格的包
  • @Ben 很棒的建议,但请注意包名已更改,不再是 googlesheets (github.com/jennybc/googlesheets),也可在 CRAN 上使用。

标签: r google-sheets


【解决方案1】:

使用 googlesheets 包,这是 Jenny Bryan 的 Google Sheets R API。这是在 R 中分析和编辑 Google 表格数据的最佳方式。它不仅可以从 Google 表格中提取数据,还可以在 Google 表格中编辑数据、创建新表格等。

可以使用install.packages("googlesheets")安装包。

有一个vignette 用于入门;请参阅her GitHub repository 了解更多信息。如果需要,您还可以从该 GitHub 页面安装该软件包的最新开发版本。

【讨论】:

  • 请在此答案中包含该软件包的一些基本用法
  • 只是为了在未来为人们节省一步 - 看起来googlesheets 包正在退役。 googlesheets4 是它的替代品。
【解决方案2】:

不确定其他用例是否具有更高的复杂性,或者是否同时发生了某些变化。在以 CSV 格式发布电子表格后,这个简单的 1-liner 对我有用:

myCSV<-read.csv("http://docs.google.com/spreadsheets/d/1XKeAajiH47jAP0bPkCtS4OdOGTSsjleOXImDrFzxxZQ/pub?output=csv")

R 版本 3.3.2 (2016-10-31)

【讨论】:

【解决方案3】:

即使您在代理后面,也有一种最简单的方法来获取 google 表格

require(RCurl)
fileUrl <- "https://docs.google.com/spreadsheets/d/[ID]/export?format=csv"
fileCSV <- getURL(fileUrl,.opts=list(ssl.verifypeer=FALSE))
fileCSVDF <-  read.csv(textConnection(fileCSV))

【讨论】:

    【解决方案4】:

    仍然可以(截至 2015 年 5 月)使用隐藏 URL &lt;sheeturl&gt;/export?format=csv 技巧 1 从 Google 电子表格中获取 CSV 文件。

    但是,在解决了这个问题之后,人们又遇到了另一个问题——数字是根据工作表的区域设置来格式化的,例如您可能会在“美国”表格中获得 1,234.15 或在“德国”表格中获得 1.234,15。要确定工作表区域设置,请转到 Google 文档中的文件 > 电子表格设置。

    现在您需要从数字列中删除小数点,以便 R 可以解析它们;根据您的数字有多大,这可能需要对每列执行多次。我写了一个简单的函数来完成这个:

    # helper function to load google sheet and adjust for thousands separator (,)
    getGoogleDataset <- function(id) {
      download.file(paste0('https://docs.google.com/spreadsheets/d/', id, '/export?format=csv'),'google-ds.csv','curl');
      lines <- scan('google-ds.csv', character(0), sep="\n");
    
      pattern<-"\"([0-9]+),([0-9]+)";
      for (i in 0:length(lines)) {
        while (length(grep(pattern,lines[i]))> 0) {
          lines[i] <- gsub(pattern,"\"\\1\\2",lines[i]);
        }
      }
      return(read.csv(textConnection(lines)));
    }
    

    您需要require(utils) 并安装 curl,但没有其他额外的软件包。

    【讨论】:

    • 您可以改用format=tsv。进入 R read.delimdec = ","
    【解决方案5】:

    我刚刚编写了一个简单的包来解决这个问题:仅使用 URL 下载 Google 表格。

    install.packages('gsheet')
    library(gsheet)
    gsheet2tbl('docs.google.com/spreadsheets/d/1I9mJsS5QnXF2TNNntTy-HrcdHmIF9wJ8ONYvEJTXSNo')
    

    更多详情在这里:https://github.com/maxconway/gsheet

    【讨论】:

    • 好的简单解决方案
    • 我喜欢它,因为它很简单,而且不需要验证即可查看工作表!
    【解决方案6】:

    更简单的方法。

    请务必仔细匹配您的网址与此处示例一的格式。您可以从 Google 电子表格编辑页面获取除 /export?format=csv 之外的所有内容。然后,只需手动将此片段添加到 URL 中,然后按此处所示使用。

    library(RCurl)
    library(mosaic)
    mydat2 <- fetchGoogle(paste0("https://docs.google.com/spreadsheets/d/",
      "1mAxpSTrjdFv1UrpxwDTpieVJP16R9vkSQrpHV8lVTA8/export?format=csv"))
    mydat2
    

    【讨论】:

      【解决方案7】:

      感谢您的解决方案!和旧的一样好用。我使用另一个修复程序来摆脱空白的第一行。当您只是排除它时,您可能会在该行“未冻结”时意外删除一个有效的观察结果。该函数中的额外指令删除任何没有时间戳的行。

      readSpreadsheet <- function(url, sheet = 1){
         library(httr)
         r <- GET(url)
         html <- content(r)
         sheets <- readHTMLTable(html, header=FALSE, stringsAsFactors=FALSE)
         df <- sheets[[sheet]]
         dfClean <- function(df){
          nms <- t(df[1,])
          names(df) <- nms
          df <- df[-1,-1] 
          df <- df[df[,1] != "",]   ## only select rows with time stamps
          row.names(df) <- seq(1,nrow(df))
          df
         }
         dfClean(df)
      }
      

      【讨论】:

        【解决方案8】:

        使用 httr 和 XML 包抓取 html 表。

        library(XML)
        library(httr)
        
        url <- "https://docs.google.com/spreadsheets/d/12MK9EFmPww4Vw9P6BShmhOolH1C45Irz0jdzE0QR3hs/pubhtml"
        
        readSpreadsheet <- function(url, sheet = 1){
          library(httr)
          r <- GET(url)
          html <- content(r)
          sheets <- readHTMLTable(html, header=FALSE, stringsAsFactors=FALSE)
          df <- sheets[[sheet]]
          dfClean <- function(df){
            nms <- t(df[1,])
            names(df) <- nms
            df <- df[-1,-1] 
            row.names(df) <- seq(1,nrow(df))
            df
          }
          dfClean(df)
        }
        df <- readSpreadsheet(url)
        df
        

        【讨论】:

        • 这让我得到一行 0 列。
        • 这对我有用,是一个有效的解决方案。但我在结果数据框中的标题下方有一个空行。
        • @hianalytics 您应该能够调整 dfClean 函数以匹配您的电子表格的特定格式
        • @jpmarindiaz 太好了,谢谢!在脚本末尾添加此 df &lt; df[-1,] 对我来说非常有用。我认为 Google 电子表格可能存在问题,因为在最初读取数据后在标题下方添加了一行 readHTMLTable(...
        • 更正:df &lt;- df[-1,] 我还在 Google 表格中冻结了第一行,我认为这导致了额外的空白行,因为它在我解冻后消失然后重新运行原始脚本 @jpmarindiaz提供。
        【解决方案9】:

        我正在为此寻找解决方案。这是一个适用于您的数据以及我自己的一些 Google 电子表格的函数。

        首先,我们需要一个从 Google 表格中读取的函数。 readGoogleSheet() 将返回一个数据框列表,对应于 Google 表格中的每个表格:

        readGoogleSheet <- function(url, na.string="", header=TRUE){
          stopifnot(require(XML))
          # Suppress warnings because Google docs seems to have incomplete final line
          suppressWarnings({
            doc <- paste(readLines(url), collapse=" ")
          })
          if(nchar(doc) == 0) stop("No content found")
          htmlTable <- gsub("^.*?(<table.*</table).*$", "\\1>", doc)
          ret <- readHTMLTable(htmlTable, header=header, stringsAsFactors=FALSE, as.data.frame=TRUE)
          lapply(ret, function(x){ x[ x == na.string] <- NA; x})
        }
        

        接下来,我们需要一个函数来清理各个表。 cleanGoogleTable() 删除由 Google 插入的空行,删除行名(如果存在)并允许您在表格开始之前跳过空行:

        cleanGoogleTable <- function(dat, table=1, skip=0, ncols=NA, nrows=-1, header=TRUE, dropFirstCol=NA){
          if(!is.data.frame(dat)){
            dat <- dat[[table]]
          }
        
          if(is.na(dropFirstCol)) {
            firstCol <- na.omit(dat[[1]])
            if(all(firstCol == ".") || all(firstCol== as.character(seq_along(firstCol)))) {
              dat <- dat[, -1]
            }
          } else if(dropFirstCol) {
            dat <- dat[, -1]
          }
        
          if(skip > 0){
            dat <- dat[-seq_len(skip), ]
          }
        
          if(nrow(dat) == 1) return(dat)
        
        
          if(nrow(dat) >= 2){
            if(all(is.na(dat[2, ]))) dat <- dat[-2, ]
          }
          if(header && nrow(dat) > 1){
            header <- as.character(dat[1, ])
            names(dat) <- header
            dat <- dat[-1, ]
          }
        
          # Keep only desired columns
          if(!is.na(ncols)){
            ncols <- min(ncols, ncol(dat))
            dat <- dat[, seq_len(ncols)]
          }
        
        
          # Keep only desired rows
          if(nrows > 0){
            nrows <- min(nrows, nrow(dat))
            dat <- dat[seq_len(nrows), ]
          }
        
          # Rename rows
          rownames(dat) <- seq_len(nrow(dat))
          dat
        }
        

        现在我们已准备好阅读 Google 表格:

        > u <- "https://docs.google.com/spreadsheets/d/0AmFzIcfgCzGFdHQ0eEU0MWZWV200RjgtTXVMY1NoQVE/pubhtml"
        > g <- readGoogleSheet(u)
        > cleanGoogleTable(g, table=1)
        
        
                 2012-Jan Mobile internet Tanzania
        1 Airtel Zantel Vodacom Tigo TTCL Combined
        
        
        > cleanGoogleTable(g, table=2, skip=1)
        
                                   BUNDLE       FEE VALIDITY     MB    Cost Sh/MB
        1             Daily Bundle (20MB)     500/=    1 day     20     500  25.0
        2            1 Day bundle (300MB)   3,000/=    1 day    300   3,000  10.0
        3             Weekly bundle (3GB)  15,000/=   7 days  3,000  15,000   5.0
        4            Monthly bundle (8GB)  70,000/=  30 days  8,000  70,000   8.8
        5         Quarterly Bundle (24GB) 200,000/=  90 days 24,000 200,000   8.3
        6            Yearly Bundle (96GB) 750,000/= 365 days 96,000 750,000   7.8
        7 Handset Browsing Bundle(400 MB)   2,500/=  30 days    400   2,500   6.3
        8                        STANDARD      <NA>     <NA>      1    <NA>  <NA>
        

        【讨论】:

        • 尝试了这个但得到Error in file(con, "r") (from #5) : cannot open the connection 知道是什么原因造成的吗?
        • 此代码现已失效。按照接受的答案的建议,改用 googlesheets 包。
        【解决方案10】:

        在新的 Google 表格中似乎不支持以 CSV 发布(或至少目前不支持),这是您创建的任何新表格的默认设置。不过,您可以通过此链接以旧的 Google 表格格式创建一个表格,该格式支持以 CSV 格式发布...https://g.co/oldsheets

        有关新旧表格的更多详细信息在这里...https://support.google.com/drive/answer/3541068?p=help_new_sheets&rd=1

        【讨论】:

        • @Andrie:我真的很喜欢这个解决方案并且被激怒了(尤其是在阅读了你的博客文章之后),因为这是一个可扩展且易于重现的工作流程。但它不起作用,我收到此错误readGoogleSheet(gdoc) Error in file(con, "r") : cannot open the connection
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多