【问题标题】:Trying to build vector of specific files within folders (R)尝试在文件夹中构建特定文件的向量 (R)
【发布时间】:2015-06-28 02:21:06
【问题描述】:

编辑:我想我通过使用 R.utils 包中的 getAbsolutePath 函数解决了这个问题。

wage_data_files <- list.files("WageData", full.names=TRUE, recursive=TRUE)
all_files <- grep(paste(toMatch, collapse = "|"), wage_data_files, value=TRUE)
files_vector <- vector()
for (i in seq_along(all_files){
files_vector <- c(files_vector, getAbsolutePath(all_files[i]))}

再次感谢大家的帮助。

#

我正在尝试在文件夹集合中提取 .csv 文件的子集。我想将它们全部放入一个向量中,然后从每个文件中提取一个特定值并将该值放入一个向量中。我的问题是关于如何将我希望从中提取值的所有文件获取到一个向量中的代码,然后我可以运行一个 for 循环来提取我想要的值并将它们放入向量中。

这是文件夹结构:

桌面 -> WageData -> 21 个文件夹 (sic.1980.annual.by.area; sic.1981.annual.by area, up to sic.2000.annual.by.area) -> 在上面的每一个文件夹大约是 1000 个 .csv 文件。

我正在尝试在每个文件夹中提取其中六个 .csv 文件:“Idaho - Statewide”、“Indiana - Statewide”、“Michigan - Statewide”、 “俄克拉荷马州——全州”、“德克萨斯州——全州”和“威斯康星州——全州”

所以总共有 126 个文件:每年 6 个,共 21 年。以下是特定文件名称的几个示例:

sic.1980.annual 40000(俄克拉荷马州——全州)

sic.1980.annual 55000(威斯康星州 -- 全州)

这是我的代码:

setwd("~/Desktop")
wage_data_files <- list.files("WageData", full.names=TRUE)
for (i in seq_along(wage_data_files)){
year_files <- list.files(wage_data_files[i])
toMatch <- c("Idaho -- Statewide", "Indiana -- Statewide", "Michigan --  Statewide", 
         "Oklahoma -- Statewide", "Texas -- Statewide", "Wisconsin -- Statewide")
dat <- data.frame()
states_vector1 <- c(dat, grep(paste(toMatch, collapse = "|"), year_files, value=TRUE))
print(states_vector1)}

当我尝试调试时,我马上遇到的一个问题是我无法正确打印结果。当我把大括号放在 print 语句之后,我得到一个这样的列表:

[[1]] [1] "sic.1980.annual 16000 (Idaho -- Statewide).csv"

[[2]] [1] "sic.1980.annual 18000 (Indiana -- Statewide).csv"

[[3]] [1] "sic.1980.annual 26000 (Michigan -- Statewide).csv"

[[4]] [1] "sic.1980.annual 40000 (Oklahoma -- Statewide).csv"

[[5]] [1] "sic.1980.annual 48000 (Texas -- Statewide).csv"

[[6]] [1] “sic.1980.annual 55000(威斯康星州——全州).csv”

[[1]] [1] "sic.1981.annual 16000 (爱达荷州 -- 全州).csv"

如你所见,它在 6 之后重复,尽管工资数据文件是长度为 21 的向量。

所以我的第一个问题是将所需的文件放入向量中。我的第二个问题是如何运行一个 for 循环读取这些文件,然后提取我想要的值。我遇到的问题是如何设置工作目录。因为,对于上述功能,工作目录是桌面。但要让 read.csv 函数工作,我必须将工作目录设置为每个单独的文件夹(例如“WageData/sic.1980.annual.by_area”、“WageData/sic.1981.annual.by_area”、等等……)

有人有什么建议吗?

谢谢。

【问题讨论】:

  • 获取文件的平面列表可能比包含目录的列表更容易。您可以使用list.files("WageData", include.dirs = FALSE, full.names = TRUE, recursive = TRUE)。如果 WageData 文件夹只包含您感兴趣的文件,您可以使用它。

标签: r


【解决方案1】:

它“在 6 之后重复”的原因是您在每个循环中创建一个新数据框,这会导致任何现有数据被删除。您需要在循环之前初始化数据框(或向量)。这是一个可能的实现,它也回答了您的第二个问题:

root_directory <- "~/Desktop/WageData"
toMatch <- c("Idaho -- Statewide", "Indiana -- Statewide", "Michigan --  Statewide", 
             "Oklahoma -- Statewide", "Texas -- Statewide", "Wisconsin -- Statewide")

folders <- list.files(root_directory, full.names = TRUE)

# initialize state_vector1 as an empty vector
states_vector1 <- c()

# loop over folders and get the full path of each file matching a pattern in the toMatch vector
for (folder in folders){
  year_files <- list.files(folder)

  # get the names of matching files, e.g. "Indiana -- Statewide.csv"
  matches <- grep(paste(toMatch, collapse = "|"), year_files, value=TRUE)

  # prepend the path to the directory to get the full path to each file
  # to get e.g. "~/Desktop/WageData/sic.1980.annual.by.area/Wisconsin -- Statewide.csv"
  matches <- vapply(matches, function(x) {file.path(folder, x)}, "", USE.NAMES = FALSE)

  # append the new matches to states_vector1
  states_vector1 <- c(states_vector1, matches)
}

# now you can loop over the vector containing the full path to each file
n_files <- length(states_vector1)
extracted_values <- rep(NA, n_files)
for (i in 1:n_files) {
  file_content <- read.csv(states_vector1[i])

  # create a function `extract_value()` which extracts the information you need from each file
  extracted_values[i] <- extract_value(file_content)
}

通过设置以下目录结构对此进行测试:

~/Desktop/WageData/sic.1980.annual.by.area/

~/Desktop/WageData/sic.1981.annual.by.area/

每个目录都有所有六个 csv 文件,我得到以下输出:

> states_vector1
 [1] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Idaho -- Statewide.csv"    
 [2] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Indiana -- Statewide.csv"  
 [3] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Michigan -- Statewide.csv" 
 [4] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Oklahoma -- Statewide.csv" 
 [5] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Texas -- Statewide.csv"    
 [6] "/Users/bene/Desktop/WageData/sic.1980.annual.by.area/Wisconsin -- Statewide.csv"
 [7] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Idaho -- Statewide.csv"    
 [8] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Indiana -- Statewide.csv"  
 [9] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Michigan -- Statewide.csv" 
[10] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Oklahoma -- Statewide.csv" 
[11] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Texas -- Statewide.csv"    
[12] "/Users/bene/Desktop/WageData/sic.1981.annual.by.area/Wisconsin -- Statewide.csv"

【讨论】:

  • 嗨@Bene,感谢您的帮助。我越来越近了。似乎有几个问题:当我打印 states_vector1 的结果时,我得到一个长度为 2646 的向量。它循环遍历“/Users/charlie/Desktop/WageData/sic.YEAR”的所有 21 个值——即它在前面1980 年为所有 126 个匹配的文件,然后在 1981 年之前,等等...当我尝试通过打印第二个“匹配”对象(带有 vapply 的那个)进行调试时,我得到“/Users/charlie/Desktop/WageData/ sic.2000.annual.by_area" 附加在每个文件名之前,包含一个长度为 126(适当长度)的向量。我
  • @CharlieMintz 如果对您有帮助,请您接受我的回答吗?谢谢
【解决方案2】:

你可以试试这个(很难测试这是否可行)。您可以从list.files 获取完整路径名,因此您可以将其用作read.csv 的文件名。我将 for 循环转换为几个 apply 循环

## Doesn't need to be in loop
toMatch <- c("Idaho -- Statewide", "Indiana -- Statewide", "Michigan --  Statewide", 
             "Oklahoma -- Statewide", "Texas -- Statewide", "Wisconsin -- Statewide")

results <- lapply(wage_data_files, function(folder) {
    year_files <- list.files(folder, full.names=T)  # get full file names (w/ path)
    states_vector1 <- grep(paste(toMatch, collapse = "|"), year_files, value=TRUE)

    ## Get a value from these files
    sapply(states_vector1, function(fname) {
        val <- read.csv(fname)[1,1]  # get the first value
    })
})

这里,返回值(存储在results)应该是一个向量列表。列表的每个元素都将包含从其中一个年份文件夹中提取的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多