4

我想使用 Google google 电子表格或表单 + 电子表格来收集 R 用户的回复并将其发送到电子表格。

这是一个最小的谷歌表单:https ://docs.google.com/forms/d/1tz2RPftOLRCQrGSvgJTRELrd9sdIrSZ_kxfoFdHiqD4/viewform

以及随附的电子表格:https ://docs.google.com/spreadsheets/d/1xemHzTdeqgMuGbsP6oqDYuMu4PymBdw7k7kMC_-Dsi8/edit#gid=102827002

我想我会像这样使用 Jenny Bryan 的 googlesheets 包:

library(googlesheets);library(dplyr)
(my_sheets <- gs_ls())

minresp <- gs_title("minimal (Responses)")
minresp %>% gs_add_row(ws = "dat", input = mtcars[20, 1:2]) 

效果很好,但是如果我包含代码并且其他人(即不是我的人)尝试使用该代码:

Error in gs_lookup(., "sheet_title", verbose) : 
  "minimal (Responsess)" doesn't match sheet_title of any sheet returned by gs_ls() (which should reflect user's Google Sheets home screen).

所以在小插图中,我看到了不同之处:

# 需要访问您不拥有的工作表吗?
# 如果您知道,请通过密钥访问它!

我认为这是允许其他人将数据输入电子表格的门票,所以我尝试了:

minresp2 <- gs_key("1xemHzTdeqgMuGbsP6oqDYuMu4PymBdw7k7kMC_-Dsi8")

产生:

Authentication will be used.
Error in gs_lookup(., "sheet_key", verbose) : 
  "1xemHzTdeqgMuGbsP6oqDYuMu4PymBdw7k7kMC_-Dsi8" doesn't match sheet_key of any sheet returned by gs_ls() (which should reflect user's Google Sheets home screen).

如果我通过谷歌登录并进行身份验证,这一切都有效,但我怎样才能做到这一点,以便用户可以添加到我的电子表格中。我不在乎一个人使用什么方法/包。如果用户只能通过函数中的使用来编辑电子表格,而不是简单地查看源代码并获取 url 并手动编辑,那就太好了,但这不是问题。

本质上,我希望能够以电子表格(或其他数据形式)收集来自 R 用户的响应,并附加到每个新用户。

4

3 回答 3

3

您的用户应使用 注册工作表gs_key(YOUR_KEY, lookup = FALSE, visibility = "private")。由于两个不同的原因,这两个论点很重要。

  • lookup = FALSE允许他们注册工作表,即使他们从未在浏览器中访问过。请注意,工作表“发布到网络”并且他们具有读取权限仍然很重要。
  • visibility = "private"影响我们为添加行所需的最终 POST 构建的 URL。要发布,可见性必须是“私有的”,否则您会收到https://github.com/jennybc/googlesheets/issues/168中报告的 405 错误。

对于下面的示例,我仍然需要将lookup信息作为已注册的 Google 表格对象的一部分,以便为表格的非所有者工作。这意味着您需要从 GitHub 安装开发版本。

为了实现您的目标,您的用户还必须具有写入权限。如何做到这一点?最简单但令人讨厌的是使工作表世界可写,如下所示。对于少数人,您可以单独授予权限。我知道没有办法让碰巧有钥匙的人可以写工作表。如果您真的想将这种权限“融入”到函数或包中,我怀疑您需要找到一种安全的方式来传输令牌,如我最初的评论中所述。

ss <- gs_new("add-row-test", input = head(iris))
#> Sheet "add-row-test" created in Google Drive.
#> Range affected by the update: "A1:E7"
#> Worksheet "Sheet1" successfully updated with 35 new value(s).
#> Worksheet dimensions: 1000 x 26.

在浏览器中,执行两项操作:
文件 > 发布到网络
共享按钮 > 在网络上公开 - Internet 上的任何人都可以查找和编辑

现在您的用户可以像这样访问和添加行:

ss_key <- "114cXPTe9whThS3lmpa3neY2vplpUX1hcnM8o8Oo6QtM"
add_row_result <- ss_key %>%
  gs_key(lookup = FALSE, visibility = "private") %>%
  gs_add_row(input = c("can", "you", "hear", "me", "now?"))
#> Authorization will not be used.
#> Worksheets feed constructed with private visibility
#> Row successfully appended.
add_row_result %>%
  gs_read()
#> Accessing worksheet titled "Sheet1"
#> Source: local data frame [9 x 5]
#>
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>          (chr)       (chr)        (chr)       (chr)   (chr)
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9           3          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5            5         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
#> 7          can         you         hear          me    now?
于 2015-10-26T23:49:40.110 回答
2

它可能是您在 Google 表格设置中使用的设置。@jennybryan 在下面的问题 #126,148 中提到了类似的内容:

https://github.com/jennybc/googlesheets/issues/148

好的,是的,我在包中遇到同样的错误,但可以在浏览器中查看它。它也不是一张旧的床单。您可以仔细检查它是否已发布到网络上?仅仅在网络上公开是不足以访问 API 的。我将创建一个新功能来测试这个!请参阅此评论以了解区别:

126(评论)

于 2015-10-26T20:13:10.597 回答
1

我已经使用了很多你的函数和包,所以我只想说声谢谢。:)

无论如何,我遇到了您过去遇到的类似问题,我通过使用此功能解决了这个问题。我基本上只是破解了Auth来自 package.json 的功能RGoogleAnalytics

# client id and secret for google drive ####
client.secret <- "YOUR SECRET"
client.id <- "YOUR ID"

# auth function to get at files in google drive ####
# and implementing it 
Auth <- function(client.id,client.secret) {

  require(httr)

  myapp <- oauth_app("google", client.id,
                     client.secret)
  google.token <- oauth2.0_token(oauth_endpoints("google"), myapp,
                                 scope = "https://www.googleapis.com/auth/drive.file")
  return(google.token)
}


token <- Auth(client.id,
              client.secret)

这在过去对我有用,但如果它不起作用,请告诉我。

于 2015-10-26T18:49:49.810 回答