R中的多文件处理,循环变量进行数据处理
Multiple file processing in R, looping over variable for data processing
我编写了几个函数来清理和处理来自美国社区调查 (ACS) 的 15 个样本。这个工作流程非常费力和重复:读取每个文件,应用我的函数,然后继续下一个调查年。
我目前的工作流程是这样的:
library(tidyverse)
library(ids)
wage_2005 <- haven::read_dta("~/Data/ACS/2005_ACS.dta") %>%
gen.wages(wage_2005) %>%
reg.variables() %>%
wage.adj(year = 2005) %>%
wage.sample(year = 2005)
然后继续到 2006 年、2007 年,依此类推,直到 2019 年。例如,
wage_2006 <- haven::read_dta("~/Data/ACS/2006_ACS.dta") %>%
gen.wages(wage_2006) %>%
reg.variables() %>%
wage.adj(year = 2006) %>%
wage.sample(year = 2006)
我想要的是使用我的清理函数处理每个样本,依次迭代循环文件,并在每个文件中使用年份变量,以便对每个调查年份应用适当的处理,然后获取并存储列表中每个调查年份的结果。
作为第一步,我编写了一些代码,使用 sapply 函数读取文件:
files <- list.files(path = "~/Data/ACS" , full.names = TRUE)
data_files <- sapply(files, function(x) {
df <- haven::read_dta(file = paste0(x)),
USE.NAMES = TRUE,
simplify = FALSE
}
)
但这会占用大量存储空间 space,因为这些文件来自人口普查局并且非常大。我坚持执行后续步骤以迭代处理每个文件、应用我的函数并将结果存储在列表中。
一些伪代码,以提供更清晰的思路:
- 年年
- 读入数据文件
- 应用函数
- 存储结果
比如说我有三组数据,比如
acs_2005 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2005)
acs_2006 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2006)
acs_2007 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2007)
data <- list(acs_2005, acs_2006, acs_2007)
假设它们将作为 csv 文件读入
lapply(1:length(data_list), function(i) write.csv(data_list[[i]],
file = paste0(names(data_list[i]), ".csv"),
row.names = FALSE))
我的自定义函数是,
wage_summarize <-
function(df, year) {
mutate(df, wage = case_when(
year == 2005 ~ wage/0.7903,
year == 2006 ~ wage/0.8112,
year == 2007 ~ wage/0.8323)) %>%
group_by(year) %>%
summarize(wage = mean(wage, na.rm = TRUE))
}
当函数依赖于年份变量以执行操作时,我将如何遍历此数据框列表?在这种情况下,假设调整 inflation?
如有任何帮助或指导,我们将不胜感激,谢谢!
这应该作为您提供的信息的指南,
library(tidyverse)
# Simulate multiple data
# that has been loaded by some
# read_data-function
data_list <- list(
mtcars,
diamonds,
iris
)
# Iterate through the list
# of data with some function
data_list <- data_list %>% map(
.f = function(x) {
x %>% mutate(
row_id = row_number()
)
}
)
这里我们加载了 data
并将其存储在一个列表中 - 它模拟了我们一次读取一个数据。我们在 using dplyr
上应用了一些函数。它输出相同长度的list
!
请参阅 Programming with Dplyr 了解有关对您的数据实施自定义 functions
的更多信息。
如果您想在 parallel
中执行此操作,这也是可能的 - 但这是 OS 特定的。如果您使用 UNIX
,那么 mclapply()
就是您的首选功能。
您要求一些指导,这就是我可以提供的信息。
为什么不将数据帧列表合并为一个 -
library(dplyr)
bind_rows(data) %>%
mutate(wage = wage/case_when(
year == 2005 ~ 0.7903,
year == 2006 ~ 0.8112,
year == 2007 ~ 0.8323)) %>%
group_by(year) %>%
summarise(wage = mean(wage, na.rm = TRUE))
# year wage
# <dbl> <dbl>
#1 2005 63.0
#2 2006 61.9
#3 2007 59.8
我编写了几个函数来清理和处理来自美国社区调查 (ACS) 的 15 个样本。这个工作流程非常费力和重复:读取每个文件,应用我的函数,然后继续下一个调查年。
我目前的工作流程是这样的:
library(tidyverse)
library(ids)
wage_2005 <- haven::read_dta("~/Data/ACS/2005_ACS.dta") %>%
gen.wages(wage_2005) %>%
reg.variables() %>%
wage.adj(year = 2005) %>%
wage.sample(year = 2005)
然后继续到 2006 年、2007 年,依此类推,直到 2019 年。例如,
wage_2006 <- haven::read_dta("~/Data/ACS/2006_ACS.dta") %>%
gen.wages(wage_2006) %>%
reg.variables() %>%
wage.adj(year = 2006) %>%
wage.sample(year = 2006)
我想要的是使用我的清理函数处理每个样本,依次迭代循环文件,并在每个文件中使用年份变量,以便对每个调查年份应用适当的处理,然后获取并存储列表中每个调查年份的结果。
作为第一步,我编写了一些代码,使用 sapply 函数读取文件:
files <- list.files(path = "~/Data/ACS" , full.names = TRUE)
data_files <- sapply(files, function(x) {
df <- haven::read_dta(file = paste0(x)),
USE.NAMES = TRUE,
simplify = FALSE
}
)
但这会占用大量存储空间 space,因为这些文件来自人口普查局并且非常大。我坚持执行后续步骤以迭代处理每个文件、应用我的函数并将结果存储在列表中。
一些伪代码,以提供更清晰的思路:
- 年年
- 读入数据文件
- 应用函数
- 存储结果
比如说我有三组数据,比如
acs_2005 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2005)
acs_2006 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2006)
acs_2007 <-
data.frame(id = random_id(n = 1000, bytes = 16, use_openssl = TRUE),
wage = runif(1000, min = 0, max = 100),
year = 2007)
data <- list(acs_2005, acs_2006, acs_2007)
假设它们将作为 csv 文件读入
lapply(1:length(data_list), function(i) write.csv(data_list[[i]],
file = paste0(names(data_list[i]), ".csv"),
row.names = FALSE))
我的自定义函数是,
wage_summarize <-
function(df, year) {
mutate(df, wage = case_when(
year == 2005 ~ wage/0.7903,
year == 2006 ~ wage/0.8112,
year == 2007 ~ wage/0.8323)) %>%
group_by(year) %>%
summarize(wage = mean(wage, na.rm = TRUE))
}
当函数依赖于年份变量以执行操作时,我将如何遍历此数据框列表?在这种情况下,假设调整 inflation?
如有任何帮助或指导,我们将不胜感激,谢谢!
这应该作为您提供的信息的指南,
library(tidyverse)
# Simulate multiple data
# that has been loaded by some
# read_data-function
data_list <- list(
mtcars,
diamonds,
iris
)
# Iterate through the list
# of data with some function
data_list <- data_list %>% map(
.f = function(x) {
x %>% mutate(
row_id = row_number()
)
}
)
这里我们加载了 data
并将其存储在一个列表中 - 它模拟了我们一次读取一个数据。我们在 using dplyr
上应用了一些函数。它输出相同长度的list
!
请参阅 Programming with Dplyr 了解有关对您的数据实施自定义 functions
的更多信息。
如果您想在 parallel
中执行此操作,这也是可能的 - 但这是 OS 特定的。如果您使用 UNIX
,那么 mclapply()
就是您的首选功能。
您要求一些指导,这就是我可以提供的信息。
为什么不将数据帧列表合并为一个 -
library(dplyr)
bind_rows(data) %>%
mutate(wage = wage/case_when(
year == 2005 ~ 0.7903,
year == 2006 ~ 0.8112,
year == 2007 ~ 0.8323)) %>%
group_by(year) %>%
summarise(wage = mean(wage, na.rm = TRUE))
# year wage
# <dbl> <dbl>
#1 2005 63.0
#2 2006 61.9
#3 2007 59.8