Сложенные циклы для вычисления среднего числа выбранных столбцов для большого набора данных - PullRequest
0 голосов
/ 06 октября 2018

У меня есть большой набор данных, содержащий результаты различных моделей моделирования.У меня есть 84 столбца, где столбцы 1-2 - это результаты прогона моделирования с одинаковыми параметрами, столбцы 3-4 - результаты второго набора из 2 прогонов с одинаковыми параметрами (отличающимися от параметров, используемых для прогонов 1-2), столбцы 5-6 - третий набор из 2 прогонов с одинаковыми параметрами (отличающимися от параметров, использованных для предыдущих прогонов) ... и т. д.

Мне нужен код для R, который позволит мне усреднить всезначения строк для моделирования выполняются с одинаковыми параметрами (например, усредняют все значения строк для столбцов 1-2, затем все значения для столбцов 3-4 ...)

Я использую следующий код, чтобы сначала сгенерировать последовательность чисел, которая представляет номера столбцов для прогонов той же модели в соответствии с количеством повторных прогонов для модели (run.num), а также общим количествомработает (total.runs).Эти переменные могут меняться в зависимости от того, как я настроил симуляцию, поэтому я хочу код, который позволит мне автоматизировать большинство шагов.

# Define parameters of model assessment
run.num <- 2
total.runs <- 84
start.seq <- seq(1, total.runs, run.num)

# Creates empty space for the sequence values
sequences <- data.frame(matrix(total.runs/run.num, run.num))

# Creates the sequences 
for (i in start.seq){
 sequence <- seq(i, i + run.num - 1, 1)
 sequences[i, 1] <- sequence[1]
 sequences[i, 2] <- sequence[2] 
}

# Is there a way to automate how many of these "sequences[i, x] are generated 
based on run.num?

# Remove NA rows
sequences <- sequences[start.seq, ]

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

Я не уверен, существует ли более простой способ сделать это, но в основном мне нужен код, в котором я могу указать, сколько повторных прогонов было выполнено для каждой модели, и получить усредненные значения для каждой из этихповторные пробеги.Это должно быть как можно более автоматизировано, чтобы мне не приходилось слишком много менять код каждый раз, когда я меняю, сколько симуляций я запускаю или сколько раз каждая симуляция повторяется.Я не мог придумать более короткий способ объяснить это, и я надеюсь, что сделал это несколько понятным.Любая помощь очень ценится! *

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Вот такой подход.Не уверен, правильно ли я понимаю вопрос, но, надеюсь, это покажет, как его можно решить.

library(tidyverse)
cols = 84
result_rows = 100
groupings = 2

fake <- data.frame(column = rep(paste0("Col_", 1:84), each = result_rows),
                   run    = rep(1:result_rows, cols),
                   result  = sample(c(1:10, NA_integer_),  cols * result_rows, replace = T)) %>%
  tidyr::spread(column, result)


output <- fake %>%
  # Pull into "long" format with a new column specifying the source column
  gather(column, result, -run) %>%
  # Extract the number from the column name
  mutate(col_num = str_remove(column, "Col_") %>% as.integer) %>%
  # Calculate what group the column belongs to
  mutate(group   = ceiling(col_num / groupings)) %>%
  # Calculate the mean per group
  group_by(group) %>%
  summarize(avg = mean(result, na.rm = T))
0 голосов
/ 06 октября 2018

Я создал меньший пример с 6 столбцами, но вы можете просто изменить total.runs на 84 для своего приложения.Я устанавливаю случайное семя для воспроизводимости.Я также поместил туда одно значение NA, чтобы показать вам, что оно может с этим справиться.Вероятно, есть много способов реализовать это, но вот один.

run.num <- 2
total.runs <- 6
start.seq <- seq(1, total.runs, run.num)

set.seed(1)
df <- data.frame(
  c1 = sample(1:10, 100, replace = T),
  c2 = sample(1:10, 100, replace = T),
  c3 = sample(1:10, 100, replace = T),
  c4 = sample(1:10, 100, replace = T),
  c5 = sample(1:10, 100, replace = T),
  c6 = c(NA, sample(1:10, 99, replace = T))
)

Сначала мы используем lapply, чтобы разбить фрейм данных на список фреймов данных, для которых вы хотите получить суммы строк.Проверьте некоторые примеры онлайн lapply, если это сбивает с толку.Это также будет работать, если run.num было 3 (но будет разбито на 4 или более, так как 4 не делит 6).

l <- lapply(start.seq, function(x) df[,x:(x + run.num - 1)])

Затем мы снова lapply, чтобы взять суммы строк и связатьрезультирующие векторы в массив данных строк.

ll <- lapply(l, function(df) rowSums(df, na.rm = T))

bind_cols(ll)
# A tibble: 100 x 3
      V1    V2    V3
   <dbl> <dbl> <dbl>
 1    10     6     3
 2    19    18    16
 3    20     9    14
 4    10    13     7
 5    15    10    15
 6    17     6     4
 7    11     8     3
 8     9     5    13
 9    10    12    10
10    20     5    14
# ... with 90 more rows

И просто для проверки работы этого первого столбца:

head(rowSums(df[,1:2], na.rm = T), 10)
 [1] 10 19 20 10 15 17 11  9 10 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...