Преобразовать список фреймов данных в один фрейм данных с несколькими столбцами, используя do.call, не работает в пределах l oop в R - PullRequest
0 голосов
/ 16 марта 2020
У

Ι есть список файлов .txt, которые содержат данные для определенных c моделей и для c месяцев. Я прочитал их все в al oop, и они хранятся в списке, как показано в следующем коде, который отлично работает!

library("dplyr")
library("tidyr")
library("reshape2") 
library("plyr")
library("data.table")
library("gridExtra")
library("varhandle")
library("lattice")
library("rowr")
library("lubridate")
library("hydroTSM")
#
####################################   
########### MONTHLY LOOP ###########
####################################
#
mons = c("OCT","NOV","DEC","JAN","FEB","MAR")
#
#####################
##### LOAD CMIP5 ####
#####################
for (i in 1:length(mons)) {
  #
  print(mons[i])
  setwd("/mnt/.../cmip5/")
  # Load all files
  files = list.files(pattern="*.txt", full.names=F)
  files
  # Read all files as data frames
  dat = lapply(files, function(x){
    read.table(x, header=F, sep=",")
  })
  # Rename files 
  names(dat) = files
  # Get all MONTHS ###LOOP HERE###
  dat_regA_cmip5 = dat[grepl(mons[i], names(dat))]
  length(dat_regA_cmip5)
  #
}

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

cmip5 = do.call(cbind, dat_regA_cmip5)

Когда я применяю вышеуказанную строку с помощью do.call на одном фрейме данных (dat_regA_cmip5: выбран вручную на один месяц, следовательно, не внутри mons l oop) он работает нормально. Но когда я помещаю его в монеты l oop, я получаю следующую ошибку:

Error in data.frame(..., check.names = FALSE) :
  arguments imply differing number of rows: 20, 19

Примечание: l oop работает для OCT, NOV и DE C, но останавливается на JAN

1 Ответ

1 голос
/ 16 марта 2020

Если наборы данных имеют разное количество строк, то лучше использовать cbind.fill из rowr

library(rowr)
cmip5 = do.call(cbind.fill, c(dat_regA_cmip5, fill = NA))

Воспроизводимый пример

df<-data.frame(a=c(1,2,3),b=c(1,2,3))
df2 <- data.frame(c = 1:2, d = 3:4)
lst1 <- list(df, df2)
do.call(cbind.fill, c(lst1, fill = NA))
#  a b  c  d
#1 1 1  1  3
#2 2 2  2  4
#3 3 3 NA NA

С обычный cbind, он возвращает ошибку

do.call(cbind, lst1)

Ошибка в data.frame (..., check.names = FALSE): аргументы подразумевают различное количество строк: 3, 2

...