Добавить файлы на основе их имен - PullRequest
1 голос
/ 18 мая 2019

Я новичок в R, и у меня есть много файлов климатических данных в текстовом формате с длинными именами в одной и той же папке, например, "tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20060101-20101231.txt", где каждый термин отделен«_» соответствует такой характеристике, как переменная, домен, институт, сценарий и т. д. Мне нужен код, который позволяет мне выбирать все файлы в моей папке, которые имеют то же имя, что и название модели, имя сценария, gcmприсвойте им имена и добавьте их по строкам.

Сначала я попытался создать список файлов и назначенных переменных для каждой части их имени, такой как имя_модели, имя_смкм и т. д., а затем создал условие, в котором я сравнивал этиПеременные в файлах с циклом.

file <- list.files ( pattern = '*.txt' ) 

group <- function(input){

index = which(file == input)

df=read.table(input,header=FALSE,sep="")

fname= unlist((strsplit(input,"_")),use.names=FALSE)

model_name=fname[3]

sce_name=fname[4]

gcm_name=fname[6]

m=1

for (m in 1:length(file)) {

  if (model_name[m]==model_name[m+1] & sce_name[m]==sce_name[m+1] & gcm_name[m]==gcm_name[m+1]) {

    data=rbind(df[m],df[m+1])

  } else  {}

}
  }

for (i in 1:length(file)) {
  group(file[i])
}

Ошибка, с которой я столкнулся с моим кодом, такова:

Ошибка в if (имя_модели [m] == имя_модели [m +]1] & sce_name [m] == sce_name [m +: пропущенное значение, где требуется TRUE / FALSE

В конце кода следует добавить файлы, соответствующие условию if acКроме того, как, например, сделать файл из этих двух файлов:

  1. tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20060101-20101231.txt

  2. tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20110101-20151231.txt

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

Ответы [ 2 ]

1 голос
/ 18 мая 2019

Я бы предложил совершенно другой подход:

Получить список всех текстовых файлов:

file <- list.files ( pattern = '*.txt' )

Прочитать все файлы в одном кадре данных:

library(dplyr)
library(readr)
df <- suppressMessages(do.call(bind_rows,lapply(file, read_csv, col_names = FALSE)))

Затем group_by полей, которые вы хотите, и записать каждый кадр в отдельный CSV-файл

df %>%
    group_by(X3, X4, X6) %>%
    do(write_csv(., paste(.$X3, .$X4, .$X6, ".csv", sep = "_")))
0 голосов
/ 18 мая 2019

Не уверен, что я получу ваш вопрос полностью, но это может помочь:

Код работает следующим образом

  1. Считайте значения файла, который вы даете в качестве ввода.
  2. Зацикливайте все остальные файлы и добавляйте их, если они соответствуют вашим условиям.

Условие If проверяет значения вашего ввода и затем сравнивает его с именами файла [m].,Если это правда, он добавляется к вашим данным.Другое исправление: вы должны использовать return(data) в конце своей функции.

file <- list.files ( pattern = '*.txt' )

group <- function(input){

  index = which(file == input)

  data=read.table(input,header=FALSE,sep="")

  fname= unlist((strsplit(input,"_")),use.names=FALSE)

  model_name=fname[3]

  sce_name=fname[4]

  gcm_name=fname[6]

  for (m in 2:length(file)) {

    index = file[m]

    df_new=read.table(file[m],header=FALSE,sep="")

    fname= unlist((strsplit(input,"_")),use.names=FALSE)

    if (model_name==fname[3] & sce_name==fname[4] & gcm_name==fname[6]) {

      data=rbind(data,df_new)

    } else  {}

  }
  return(data)
}

group(file[1])

Проблемы, которые еще предстоит решить: вы должны исправить, если вы нене вводите первый файл.Поскольку этот код использует файл, который вы вводите в вашей функции group.Но цикл for идет со вторым файлом.Поэтому, если вы используете group(file[3]), первый файл будет пропущен, а третий будет удвоен.Вы можете использовать что-то вроде другого, если условие.if(file==input){skip} (не фактический синтаксис, просто для идеи, также убедитесь, что вы правильно установили диапазон цикла)

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