Объединение вложенных элементов списка с похожими именами в R - PullRequest
0 голосов
/ 24 сентября 2019

Этот вопрос является продолжением предыдущего вопроса, который я задал Объединение данных на основе пользовательского ввода в 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"))), но очевидно, что при работе со списками должно быть что-то другое.

Любая помощь с сортировкой этого будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Мне кажется, я понимаю, что вы пытаетесь сделать.Попробуйте работать с функциями, которым требуется аргумент данных и которые возвращают данные при выполнении функции.

Вместо функций, управляющих данными в глобальной среде.

Вот пример:

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()
0 голосов
/ 24 сентября 2019

Решает ли ваша проблема следующее:

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

finalDf = bind_rows(mylist[reqdNames])

Возможно, я неправильно понял проблему.Дайте мне знать, если это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...