首页 > 解决方案 > 在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")))但显然在使用列表时必须有一些不同的东西。

标签: r

解决方案


我想我明白你想要做什么。尝试使用需要数据参数并在函数执行时返回数据的函数。

而不是在全局环境中操作数据的函数。

这是一个例子:

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()

推荐阅读