Автоматизировать сохранение в цикле - PullRequest
0 голосов
/ 29 августа 2018

Я хочу автоматизировать следующий код.

df.f1 <- c2d(fdat.s1, 1, 15000)
save(df.f1,file="../RESULTS/nl_final__df_1_1.rda")
df.f2 <- c2d(fdat.s1, 15000, 30000)
save(df.f2,file="../RESULTS/nl_final__df_1_2.rda")
df.f3 <- c2d(fdat.s1, 30000, 45000)
save(df.f3,file="../RESULTS/nl_final__df_1_3.rda")

Я пытался сделать это. Но я боролся с тем, как автоматически изменить df.f1 в цикле.

vec <- c(1,15000,30000,45000)
for(i in 1:3){
  df.f1 <- c2d(fdat.s1, vec[i], vec[i+1])
  save(df.f1,file=paste("../RESULTS/nl_mod_df_1_",i,".rda"))
}

Есть ли какой-нибудь эффективный способ, кроме цикла?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Редактировать : заранее, эффективность - относительный термин. Что-то не так с вашим текущим методом? Этот ответ был написан исходя из того, что вы работаете с несколькими наборами данных (даже если подмножества одного и того же исходного набора), но с тех пор кажется, что работа со всеми данными в list невозможна (из-за размера данных). Последнее ограничение сводит на нет преимущество работы со списком фреймов, но я оставлю здесь ответ для записи.


Я предлагаю иметь дело с list s (ref: Как мне составить список фреймов данных? ). Кроме того, это может быть сделано с mapply.

Сначала давайте сделаем вектор «разрывов» (как вы сделали):

brks <- seq(0L, 45000L, by=15000L)
brks
# [1]     0 15000 30000 45000

(«Как» вы генерируете это не критично, просто у вас есть вектор, который включает в себя каждую из точек останова, включая также первую и последнюю.) Мы будем использовать «все, кроме последнего» и «все, кроме первого» в двух отдельных векторах, так что вы можете видеть, что мы будем охватывать первый элемент каждого, затем второй элемент каждого и т. д .:

brks[-length(brks)]
# [1]     0 15000 30000
brks[-1]
# [1] 15000 30000 45000

Хотя это технически не является обязательным требованием. Я предполагаю, что ваши диапазоны должны быть смежными, поэтому использование вектора для связи гарантирует непрерывность и защиту от обновления одного вектора, а не другого. Вы, конечно, можете сделать (вместо) два независимых вектора.

mapply - функция, похожая на «застежку-молнию», где mapply(fun, 1:3, 11:13, SIMPLIFY=FALSE) эффективно list(fun(1,11), fun(2,12), fun(3,13)).

ret <- mapply(function(a,b) c2d(fdat.s1, a, b),
              brks[-length(brks)], brks[-1],
              SIMPLIFY=FALSE)

(SIMPLIFY=FALSE сохраняет его как list. Многие из *apply функций, например, сводят вещи к векторам или матрицам, если есть такая возможность, что может быть проблематично, если это не то, что вы ожидаете. усложнив это, мы увидим sapply(..., simplify=FALSE) и mapply(..., SIMPLIFY=FALSE), поэтому немного разные варианты для каждого.)

На этом этапе вы можете перебирать данные и делать все, что вам нужно, в том числе:

mapply(function(dat, nm) save(dat, file=nm),
       ret, sprintf("../RESULTS/nl_mod_df_1_%d.rda", brks[-length(brks)]))

Caveat emptor: не проверено, так как я не знаю, что такое c2d, и у меня нет ваших данных. Я считаю, что концепция достаточно твердая.

0 голосов
/ 29 августа 2018

Возможно, комбинация предварительного создания набора данных с вызовом get - это то, что вам нужно?

df.f1 <- c2d(fdat.s1, 1, 15000)
df.f2 <- c2d(fdat.s1, 15000, 30000)
df.f3 <- c2d(fdat.s1, 30000, 45000)

lapply(
  c(1, 2, 3),
  function(i){
    save(get(paste0("df.f", i)), file = paste("../RESULTS/nl_mod_df_1_", i, ".rda"))
  }
)
...