从谷歌电子表格将数据导入R

Posted

技术标签:

【中文标题】从谷歌电子表格将数据导入R【英文标题】:Importing data into R from google spreadsheet 【发布时间】: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 上使用。 【参考方案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)

【讨论】:

这是最好的答案,非常感谢。请注意它也适用于这种格式:docs.google.com/spreadsheets/d/SPREEDSHEET_ID/gviz/…,这样您就可以选择您想要的标签(对于带有许多标签的工作表很有用)【参考方案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

以上是关于从谷歌电子表格将数据导入R的主要内容,如果未能解决你的问题,请参考以下文章

用于将数据从谷歌电子表格加载到 bigquery 的独立脚本

无法从谷歌电子表格中读取

如何从谷歌电子表格中获取 json 数据

通过在云中运行的笔记本从谷歌驱动器访问电子表格文件

使用Chartrangeslider进行Google可视化,并从Google文档电子表格导入数据

如何从谷歌电子表格中动态变化的单元格中保存最小值和最大值?