Создание фрейма данных из цикла по списку фреймов данных в R - PullRequest
0 голосов
/ 03 июля 2018

У меня большой набор данных, который организован в виде списка из 1044 кадров данных. Каждый кадр данных представляет собой профиль, который содержит одни и те же данные для разных станций и времени. Я пытаюсь создать фрейм данных, который содержит выходные данные моей функции fitsObs, но мой текущий код проходит только через один фрейм данных. Есть идеи?

    i=1
start=1
for(i in 1:1044){
  station1 <- surveyCTD$stations[[i]]
  df1 <- surveyCTD$data[[i]]
  date1 <- surveyCTD$dates[[i]]

  fitObs <- fitTp2(-df1$depth, df1$temp)

  if(start==1){
    start=0
    dfout <- data.frame(
      date=date1
      ,station=station1
    )
    names(fitObs) <- paste0(names(fitObs),"o")
    dfout<-cbind(dfout, df1$temp, df1$depth)
    dfout <- cbind(dfout, fitObs)

  }
}

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Я создал воспроизводимый пример того, что вы спрашиваете. Я также предполагаю, что вы можете настроить концепции в этом общем примере в соответствии со своей собственной проблемой. Будет проще, если вы приведете пример своего списка в будущем.

Сначала мы создадим некоторые воспроизводимые данные

a <- c(10,20,30,40)
b <- c(5,10,15,20)
c <- c(20,25,30,35)
df1 <- data.frame(x=a+1,y=b+1,z=c+1)
df2 <- data.frame(x=a,y=b,z=c)
ls1 <- list(df1,df2)

Который выглядит так

print(ls1)
[[1]]
   x  y  z
1 11  6 21
2 21 11 26
3 31 16 31
4 41 21 36

[[2]]
   x  y  z
1 10  5 20
2 20 10 25
3 30 15 30
4 40 20 35

Итак, теперь у нас есть два кадра данных в одном списке. Следующий код должен затем пройтись по столбцам в каждом фрейме данных списка и применить функцию mean () к данным в столбце. Вы можете изменить это на строку, выбрав «1» вместо «2».

df <- do.call("rbind", lapply(ls1, function(x) apply(x,2,mean)))
as.data.frame(df)
print(df)
   x   y   z
1 26 13.5 28.5
2 25 12.5 27.5

Вы должны иметь возможность заменить mean () на любую функцию, которую вы написали для своих данных. Дайте мне знать, если это поможет.

0 голосов
/ 03 июля 2018

Подумайте о создании обобщенной функции, которая будет вызываться с помощью i Map (оболочка для mapply, m ultiple, поэлементный член итератора семейства apply ) для построения списка фреймы данных с выходом fitObs . И передать все объекты одинаковой длины в конструктор data.frame().

Затем за пределами цикла запустите do.call, чтобы получить окончательный одиночный добавленный фрейм данных всех 1044 меньших фреймов данных (при условии, что каждый из них содержит одинаковое количество столбцов):

# GENERALIZED FUNCTION
add_fit_obs <- function(dt, st, df) {

   fitObs <- fitTp2(-df$depth, df$temp)
   names(fitObs) <- paste0(names(fitObs),"o")

   tmp <- data.frame(
       date = dt,
       station = st,
       depth = df1$depth,
       temp = df1$temp,
       fitObs      
    )

   return(tmp)
}

# LIST OF DATA FRAMES
df_list <- Map(add_fit_obs, surveyCTD$stations, surveyCTD$dates, surveyCTD$data) 
# EQUIVALENTLY:
# df_list <- mapply(add_fit_obs, surveyCTD$stations, surveyCTD$dates, surveyCTD$data, SIMPLIFY=FALSE)

# SINGLE DATAFRAME
master_df <- do.call(rbind, df_list)
0 голосов
/ 03 июля 2018

С первого взгляда я бы попробовал два способа его отладки. Сначала распечатайте заголовок DF, чтобы понять поведение вашего цикла, затем проверьте диапазон вашей переменной dfout, похоже, переменная является локальной для вашего цикла.

Более того, ваша переменная i вне цикла ничего не меняет в вашем цикле.

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