从谷歌电子表格将数据导入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 <sheeturl>/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.delim
和 dec = ","
。【参考方案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 < df[-1,]
对我来说非常有用。我认为 Google 电子表格可能存在问题,因为在最初读取数据后在标题下方添加了一行 readHTMLTable(...
更正:df <- 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 的独立脚本