【问题标题】:Combining nested list items with similar names in R在R中组合具有相似名称的嵌套列表项
【发布时间】:2019-10-25 02:44:40
【问题描述】:

这个问题在某种程度上是我之前提出的问题Combining data based on user input in 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 的新列表中987654325@。然后用户可以调用来自特定站点的所有数据。

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"))) 的所有内容,但显然在使用列表时必须有所不同。

【问题讨论】:

  • 嗨,bmdanhof。您对以下答案的理解如何? :-)

标签: r


【解决方案1】:

以下是否解决了您的问题:

library(dplyr)
reqdNames = names(mylist)[grepl("asw",names(mylist))]

finalDf = bind_rows(mylist[reqdNames])

我可能误解了这个问题。让我知道它是否有效。

【讨论】:

    【解决方案2】:

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

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

    这是一个例子:

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

    【讨论】:

      猜你喜欢
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2023-02-23
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多