rio包
我们推荐的 R 包是:rio。名称“rio”是“RI/O”(输入/输出)的缩写。
它的功能import()
和export()
可以处理许多不同的文件类型(例如.xlsx、.csv、.rds、.tsv)。当您提供这些函数的文件路径(包括“.csv”之类的文件扩展名)时,rio将读取扩展名并使用正确的工具导入或导出文件。
注意:如果您尝试导入列表,请使用import_list()
以完整的原始结构和内容导入它。
rio::import_list("my_list.Rdata")
here包
here()
可以很容易地告诉 R 在哪里找到和保存你的文件——本质上,它构建了文件路径。
与 R 项目结合使用,here允许您描述 R 项目中文件相对于 R 项目根目录(顶级文件夹)的位置。当 R 项目可能由多个人/计算机共享或访问时,这很有用。它可以防止由于不同计算机上的唯一文件路径而导致的复杂性(例如 "C:/Users/Laura/Documents..."
,通过在所有用户共同的位置(R 项目根目录)“启动”文件路径)。
这是here()
在 R 项目中的工作方式:
- 当第一次在 R 项目中加载here包时,它会在 R 项目的根文件夹中放置一个名为“.here”的小文件作为“基准”或“锚”
- 在您的脚本中,要引用 R 项目的子文件夹中的文件,您可以使用该函数
here()
来构建与该锚点相关的文件路径 - 要构建文件路径,请将根目录以外的文件夹名称写在引号内,用逗号分隔,最后以文件名和文件扩展名结尾,如下所示
here()
文件路径可用于导入和导出
例如,在下面,为函数import()
提供了一个用here()
.
linelist <- import(here("data", "linelists", "ebola_linelist.xlsx"))
该命令here("data", "linelists", "ebola_linelist.xlsx")
实际上提供了用户计算机唯一的完整文件路径:
"C:/Users/Laura/Documents/my_R_project/data/linelists/ebola_linelist.xlsx"
提示:如果您不确定“.here”根设置在哪里,请here()
使用空括号运行该函数。
绝对路径(不推荐)
linelist <- import("C:/Users/Laura/Documents/analysis/data/linelists/ebola_linelist.xlsx")
导入数据
导入位于“工作目录”或 R 项目根文件夹中的 csv 文件:
linelist <- import("linelist_cleaned.csv")
导入位于 R 项目子文件夹下的文件
如“data”和“linelists”子文件夹中的 Excel 工作簿的第一张表(使用 构建的文件路径here()
):
linelist <- import(here("data", "linelists", "linelist_cleaned.xlsx"))
使用绝对文件路径导入数据框(.rds 文件):
linelist <- import("C:/Users/Laura/Documents/tuberculosis/data/linelists/linelist_cleaned.rds")
特定的 Excel 工作表
my_data <- import("my_excel_file.xlsx", which = "Sheetname")
# Demonstration: importing a specific Excel sheet when using relative pathways with the 'here' package
linelist_raw <- import(here("data", "linelist.xlsx"), which = "Sheet1")
缺失值
您可能需要指定数据集中的哪些值应被视为缺失。正如缺失数据页面中所述,R 中缺失数据的值为NA
,但您要导入的数据集可能使用 99、“缺失”或只是空字符空间“”。
使用na =
参数 forimport()
并在引号内提供值(即使它们是数字)。您可以通过将它们包含在向量中来指定多个值,c()
如下所示。
linelist <- import(here("data", "my_linelist.xlsx"), na = "99")
linelist <- import(here("data", "my_linelist.csv"), na = c("Missing", "", " "))
跳过行
有时,您可能希望避免导入一行数据。如果在 .xlsx 或 .csv 文件上skip =
使用import()
from rio ,则可以使用参数执行此操作。提供要跳过的行数。
linelist_raw <- import("linelist_raw.xlsx", skip = 1) # does not import header row
不幸的是skip =
只接受一个整数值,而不是一个范围(例如“2:10”不起作用)。要跳过从顶部不连续的特定行的导入,请考虑多次导入并使用bind_rows()
from dplyr。
管理第二个标题行
有时,您的数据可能有第二行,例如,如果它是如下所示的“数据字典”行。这种情况可能会出现问题,因为它可能导致所有列都作为类“字符”导入。
下面是这种数据集的一个例子(第一行是数据字典)。
要删除第二个标题行,您可能需要导入两次数据。
- 导入数据以存储正确的列名
- 再次导入数据,跳过前两行(标题和第二行)
- 将正确的名称绑定到缩减的数据帧上
用于绑定正确列名的确切参数取决于数据文件的类型(.csv、.tsv、.xlsx 等)。这是因为rio对不同的文件类型使用不同的函数(见上表)。
对于 Excel 文件:( col_names =
)
# import first time; store the column names
linelist_raw_names <- import("linelist_raw.xlsx") %>% names() # save true column names
# import second time; skip row 2, and assign column names to argument col_names =
linelist_raw <- import("linelist_raw.xlsx",
skip = 2,
col_names = linelist_raw_names
)
对于 CSV 文件:( col.names =
)
# import first time; sotre column names
linelist_raw_names <- import("linelist_raw.csv") %>% names() # save true column names
# note argument for csv files is 'col.names = '
linelist_raw <- import("linelist_raw.csv",
skip = 2,
col.names = linelist_raw_names
)
制作数据字典
dict <- linelist_2headers %>% # begin: linelist with dictionary as first row
head(1) %>% # keep only column names and first dictionary row
pivot_longer(cols = everything(), # pivot all columns to long format
names_to = "Column", # assign new column names
values_to = "Description")
合并两个标题行
在某些情况下,当您的原始数据集有两个标题行(或者更具体地说,第二行数据是辅助标题)时,您可能希望“组合”它们或将第二个标题行中的值添加到第一个标题行中。
下面的命令将定义数据帧的列名称作为第一个(True)标头的组合(粘贴在一起),其值在下面的值(在第一行中)。
names(my_data) <- paste(names(my_data), my_data[1, ], sep = "_")
谷歌表格
您可以使用Googlesheet4包从在线Google电子表格导入数据,并通过对电子表格进行验证。
pacman::p_load("googlesheets4")
Gsheets_demo <- read_sheet("https://docs.google.com/spreadsheets/d/1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY/edit#gid=0")
#也可以仅使用Sheet ID导入纸张,其中URL的较短部分:
Gsheets_demo <- read_sheet("1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY")
另一个包googledrive提供了用于编写、编辑和删除 Google 表格的有用功能。例如,使用此包中的gs4_create()
andsheet_write()
函数。
以下是一些其他有用的在线教程:
基本的 Google 表格导入教程
更详细的教程
googlesheets4 和 tidyverse 之间的交互
多个文件 - 导入、导出、拆分、组合
有关如何导入和合并多个文件或多个 Excel 工作簿文件的示例,请参阅迭代、循环和列表页面。该页面还包含有关如何将数据框拆分为多个部分并单独导出每个部分或作为 Excel 工作簿中的命名工作表的示例。
从 Github 导入
将数据直接从 Github 导入 R 可能非常容易,或者可能需要几个步骤 - 取决于文件类型。以下是一些方法:
CSV 文件
使用 R 命令将 .csv 文件直接从 Github 导入 R 很容易。
- 转到 Github 存储库,找到感兴趣的文件,然后单击它
- 单击“Raw”按钮(然后您将看到“原始”csv 数据,如下所示)
- 复制 URL(网址)
- 将 URL 放在
import()
R 命令中的引号中
手动数据输入
按行输入
使用tribble
来自tidyverse 的tibble包中的函数(在线 tibble 参考)。
请注意列标题以波浪号( ~
) 开头。另请注意,每一列只能包含一类数据(字符、数字等)。您可以使用制表符、间距和新行来使数据输入更加直观和可读。值之间的空格无关紧要,但每一行都由一行新代码表示。例如:
# create the dataset manually by row
manual_entry_rows <- tibble::tribble(
~colA, ~colB,
"a", 1,
"b", 2,
"c", 3
)
按列输入
由于数据框由向量(垂直列)组成,因此在 R 中手动创建数据框的基本方法希望您定义每一列,然后将它们绑定在一起。这在流行病学中可能是违反直觉的,因为我们通常会按行考虑我们的数据(如上所述)。
# define each vector (vertical column) separately, each with its own name
PatientID <- c(235, 452, 778, 111)
Treatment <- c("Yes", "No", "Yes", "Yes")
Death <- c(1, 0, 1, 0)
# combine the columns into a data frame, by referencing the vector names
manual_entry_cols <- data.frame(PatientID, Treatment, Death)
注意:所有向量的长度必须相同(值的数量相同)。
API
“自动化编程接口”(API)可用于直接从网站请求数据。API 是一组规则,允许一个软件应用程序与另一个应用程序交互。客户(您)发送“请求”并接收包含内容的“响应”。R 包httr和jsonlite可以促进这个过程。
每个启用 API 的网站都有自己的文档和细节供您熟悉。有些网站是公开的,任何人都可以访问。其他的,例如具有用户 ID 和凭据的平台,需要进行身份验证才能访问其数据。
不用说,必须有互联网连接才能通过 API 导入数据。我们将简要介绍使用 API 导入数据的示例,并将您链接到更多资源。
注意:请记住,数据可能会在没有 API 的网站上发布*,这可能更容易检索。例如,可以通过提供站点 URL 来访问发布的 CSV 文件,
如从 Github 导入部分中所述的import()。
HTTP 请求
API 交换最常通过 HTTP 请求完成。HTTP 是超文本传输协议,是客户端和服务器之间请求/响应的底层格式。确切的输入和输出可能会因 API 的类型而异,但过程是相同的——来自用户的“请求”(通常是 HTTP 请求),通常包含查询,然后是“响应”,包含有关请求和可能请求的内容。
以下是HTTP 请求的一些组成部分:
- API 端点的 URL
- “方法”(或“动词”)
- 标头
- 身体
HTTP 请求“方法”是您要执行的操作。两种最常见的 HTTP 方法是GET
,POST
但其他可能包括PUT
, DELETE
,PATCH
等。在将数据导入 R 时,您很可能会使用GET
.
在您提出请求后,您的计算机将收到格式与您发送的内容类似的“响应”,包括 URL、HTTP 状态(您想要的是状态 200!)、文件类型、大小和所需内容。然后,您需要解析此响应并将其转换为 R 环境中的可用数据框。
包
httr包非常适合在 R 中处理 HTTP 请求。它几乎不需要 Web API 的先验知识,并且可供不太熟悉软件开发术语的人使用。另外,如果 HTTP 响应是 .json,可以使用jsonlite来解析响应。
# load packages
pacman::p_load(httr, jsonlite, tidyverse)
公开数据
下面是一个 HTTP 请求示例,借鉴自Trafford Data Lab的教程。该站点还有其他一些学习资源和 API 练习。
场景:我们要导入英国特拉福德市的快餐店列表。这些数据可以从食品标准局的 API 中获取,该 API 为英国提供食品卫生评级数据。
以下是我们请求的参数:
- HTTP 动词:GET
- API 端点 URL:http ://api.ratings.food.gov.uk/Establishments
- 选择参数:名称、地址、经度、纬度、businessTypeId、ratingKey、localAuthorityId
- 标头:“x-api-version”,2
- 数据格式:JSON、XML
- 文档:http ://api.ratings.food.gov.uk/help
R代码如下:
# prepare the request
path <- "http://api.ratings.food.gov.uk/Establishments"
request <- GET(url = path,
query = list(
localAuthorityId = 188,
BusinessTypeId = 7844,
pageNumber = 1,
pageSize = 5000),
add_headers("x-api-version" = "2"))
# check for any server error ("200" is good!)
request$status_code
# submit the request, parse the response, and convert to a data frame
response <- content(request, as = "text", encoding = "UTF-8") %>%
fromJSON(flatten = TRUE) %>%
pluck("establishments") %>%
as_tibble()
需要身份验证
某些 API 需要身份验证 - 以便您证明自己的身份,以便您可以访问受限数据。要导入这些数据,您可能需要首先使用 POST 方法提供用户名、密码或代码。这将返回一个访问令牌,可用于后续 GET 方法请求以检索所需数据。
下面是一个从Go.Data查询数据的示例,它是一个爆发调查工具。Go.Data使用 API 进行 Web 前端和用于数据收集的智能手机应用程序之间的所有交互。Go.Data在全球范围内使用。由于爆发数据很敏感,并且您应该只能访问爆发的数据,因此需要进行身份验证。
下面是一些示例 R 代码,使用httr和jsonlite连接到Go.Data API 以导入爆发后的联系人跟进数据。
# set credentials for authorization
url <- "https://godatasampleURL.int/" # valid Go.Data instance url
username <- "username" # valid Go.Data username
password <- "password" # valid Go,Data password
outbreak_id <- "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx" # valid Go.Data outbreak ID
# get access token
url_request <- paste0(url,"api/oauth/token?access_token=123") # define base URL request
# prepare request
response <- POST(
url = url_request,
body = list(
username = username, # use saved username/password from above to authorize
password = password),
encode = "json")
# execute request and parse response
content <-
content(response, as = "text") %>%
fromJSON(flatten = TRUE) %>% # flatten nested JSON
glimpse()
# Save access token from response
access_token <- content$access_token # save access token to allow subsequent API calls below
# import outbreak contacts
# Use the access token
response_contacts <- GET(
paste0(url,"api/outbreaks/",outbreak_id,"/contacts"), # GET request
add_headers(
Authorization = paste("Bearer", access_token, sep = " ")))
json_contacts <- content(response_contacts, as = "text") # convert to text JSON
contacts <- as_tibble(fromJSON(json_contacts, flatten = TRUE)) # flatten JSON to tibble
注意:如果您从需要身份验证的 API 导入大量数据,则可能会超时。为避免这种情况,请在每个 API GET 请求之前再次检索 access_token 并尝试在查询中使用过滤器或限制。
提示: jsonlite包中的fromJSON()
函数在第一次执行时不会完全取消嵌套,因此您可能仍然在生成的 tibble 中有列表项。您将需要进一步取消嵌套某些变量;取决于您的 .json 的嵌套程度。要查看这方面的更多信息,请查看jsonlite包的文档,例如function。flatten()
有关更多详细信息,请查看LoopBack Explorer上的文档、联系人跟踪页面或Go.Data Github 存储库上的 API 提示
您可以在此处阅读有关httr包的更多信息。