r - 在R中组合具有相似名称的嵌套列表项
问题描述
这个问题在某种程度上是我之前提出的基于用户输入在 R 中组合数据的问题的延续。建议将我的数据存储在列表中,而不是作为全局环境中的单个项目。因此,我试图将所有类似的文件类型(例如 .csv)导入列表列表。每个嵌套列表代表多个时间序列 .csv 文件之一。这目前使用以下代码工作:
ImportData <- function(mypattern,...)
{
mypattern <- readline(prompt = "Enter File Type:")
temp <- list.files(".", pattern=mypattern)
myfiles <- lapply(temp, fread, skip = 1)
names(myfiles) <- gsub("-.*", "", temp)
header <- c("index","DateTime", "Voltage")
myfiles <<- lapply(myfiles, setNames, header)
}
ImportData()
下一步是将时间序列数据列表与表示来自同一站点的数据的相似名称组合起来。运行上述函数后,myfiles
包含名称如 ASW1.csv、ASW1_10Sept.csv、ASW1_2017 以及其他具有不同缩写的列表(例如 CSW)。我使用以下功能的目标是提示用户输入站点名称(例如 ASW1),并将myfiles
列表中名称包含 ASW1 的每个列表组合并按日期排序到名为 ASW1 的新列表中myfiles
。然后用户可以调用来自特定站点的所有数据。
CombineData <- function()
{
Site <- invisible(readline(prompt = "Enter Site Name:"))
myfiles[[Site]] <<- rbindlist(mget(apropos(Site), inherits = TRUE))
}
CombineData()
我遇到的问题是,当运行CombineData
一个空列表时,会添加一个空列表,myfiles
而不是一个包含任何列表中所有数据的列表,其中提供的名称为Site
. 我可以手动组合列表:
ASW1 <- myfiles[c(1,2,3,4)]
ASW1 <- rbindlist(ASW1)
但我的目标是让这个过程尽可能自动化。在我的代码的先前版本中,我使用以下内容来获取包含特定名称的所有内容,do.call(rbind, mget(ls(pattern = "^ASW1")))
但显然在使用列表时必须有一些不同的东西。
解决方案
我想我明白你想要做什么。尝试使用需要数据参数并在函数执行时返回数据的函数。
而不是在全局环境中操作数据的函数。
这是一个例子:
MakeData <- function(abrr = 'ASW',nfiles = 10){
for(i in 1:nfiles){
lst <- list(a = 1:10,
b = rnorm(10)>0,
c = sample(LETTERS,10))
write.csv(lst,paste0("test_",abrr,i,".csv"))
}
}
ImportData <- function(mypattern)
{
temp <- list.files(".", pattern=mypattern)
myfiles <- lapply(temp, read.csv)
names(myfiles) <- gsub("-.*", "", temp)
myfiles
}
CombineData <- function(datalst,get = 'a')
{
lst <- lapply(datalst, function(x) x[[get]])
do.call(rbind, lst)
}
set.seed(314)
MakeData("ASW")
impdat <- ImportData("ASW")
CombineData(impdat,'b')
返回:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
test_ASW1.csv FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE FALSE
test_ASW10.csv FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE FALSE FALSE
test_ASW2.csv TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE
test_ASW3.csv FALSE TRUE TRUE TRUE FALSE FALSE TRUE FALSE TRUE FALSE
test_ASW4.csv FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
test_ASW5.csv TRUE TRUE TRUE TRUE FALSE FALSE TRUE FALSE TRUE TRUE
test_ASW6.csv TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE
test_ASW7.csv TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
test_ASW8.csv FALSE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE
test_ASW9.csv FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE
或用于tidyverse
加载和处理管道中的数据,就像我喜欢做的那样:
require(tidyverse)
data.frame(filename = list.files(".", pattern = "ASW"), stringsAsFactors = F) %>%
mutate(lst = map(filename,~read.csv(.x)),
dat = map(lst, ~as.data.frame(t(.x[['b']])))) %>%
select(filename,dat) %>%
unnest()