Применение нескольких функций к списку матриц и вывод ответов в кадре данных - PullRequest
3 голосов
/ 20 сентября 2019

У меня есть следующая матрица:

mat<- matrix(c(1,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,
   2,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
   0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
   0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,
   1,1,0,0,0,0,0,0,1,0,1,2,1,0,0,0), nrow=16, ncol=6)
dimnames(mat)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
          c("1", "2", "3", "4", "5", "6"))

Я создал список матриц, используя следующую функцию:

lapply(seq_len(ncol(mat) - 1), function(j) do.call(cbind, 
       lapply(seq_len(ncol(mat) - j), function(i) rowSums(mat[, i:(i + j)]))))

В этой функции столбцы в исходной матрице объединяютсяиспользуя метод движущегося окна.Во-первых, размер окна равен 2, так что данные в двух столбцах объединяются.Окно сдвигается на 1 шаг (1 столбец), и следующий набор из двух столбцов объединяется.Вывод представляет собой матрицу для каждого размера окна.Размер окна продолжает увеличиваться, так что окно увеличивается до 3 столбцов, а результаты из 3 столбцов выводятся в новую матрицу.Это продолжается до тех пор, пока в окне не появится размер максимального количества столбцов.

Мне нужно запустить ряд функций для каждой матрицы в списке и вывести ответы в кадр данных.Мне нужно применить следующие функции:

  1. Рассчитать общую частоту для каждой строки (т. Е. Итоги строк).Я попытался выполнить эту функцию:

    freq <- rowSums(mat[i:(i + j),])
    
  2. Рассчитать среднюю частоту для каждой строки (т. Е. Итоги строк / длина строки).Я попробовал эту функцию:

    mean_freq <- rowSums(mat[i:(i + j),])/length(mat[i:(i + j),])
    
  3. Умножить размер окна * pi * 25.

    total_window_size <- length(ncol(mat) - j))*pi*25
    
  4. Разделить среднюю частоту для каждогострока по общему размеру окна.

    density <- mean_freq/total_window_size
    

Ниже приведены ожидаемые результаты для вышеприведенных функций для каждой матрицы в этом примере списка (т. Е. result_mat1, result_mat2 ...).Фрейм данных result_df объединяет все результаты для каждого вспомогательного фрейма данных и является конечным результатом, который мне нужен:

df для размера окна 2

result_mat1 <- data.frame( window_size= rep("2",80), 
                     combined_cols= c(rep("1_2",16), rep("2_3",16), rep("3_4",16), rep("4_5",16), rep("5_6",16)),
                     row_names= c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"),
                     freq=c(6,3,2,2,6,2,1,2,1,2,3,2,1,2,3,2),
                     mean_freq=(c(6,3,2,2,6,2,1,2,1,2,3,2,1,2,3,2)/5), 
                     total_window_size= rep(157.08, 16))
result_mat1$density<- result_mat1$mean_freq/result_mat1$total_window_size             

df для размера окна 3

result_mat2 <- data.frame( window_size= rep("3",64), 
                     combined_cols= c(rep("1_2_3",16), rep("2_3_4",16), rep("3_4_5",16), rep("4_5_6",16)),
                     row_names= c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"),
                     freq=c(6,4,3,3,7,3,1,2,1,2,3,2,1,2,4,2),
                     mean_freq=(c(6,4,3,3,7,3,1,2,1,2,3,2,1,2,4,2)/5), 
                     total_window_size= rep(235.62, 16))
result_mat2$density <- result_mat2$mean_freq/result_mat2$total_window_size

df для размера окна 4

result_mat3 <- data.frame( window_size= rep("4",48), 
                                 combined_cols= c(rep("1_2_3_4",16), rep("2_3_4_5",16), rep("3_4_5_6",16)),
                                 row_names= c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"),
                                 freq=c(6,3,3,3,7,3,1,2,1,2,3,2,1,2,4,2),
                                 mean_freq=(c(6,3,3,3,7,3,1,2,1,2,3,2,1,2,4,2)/5), 
                                 total_window_size= rep(314, 16))
result_mat3$density <- result_mat3$mean_freq/result_mat3$total_window_size

df для размера окна 5

result_mat4 <- data.frame( window_size= rep("5",32), 
                      combined_cols= c(rep("1_2_3_4_5",16), rep("2_3_4_5_6",16)),
                      row_names= c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"),
                      freq=c(6,3,2,2,6,2,1,2,1,2,3,2,1,2,4,2),
                      mean_freq=(c(6,3,2,2,6,2,1,2,1,2,3,2,1,2,4,2)/5), 
                      total_window_size= rep(392.5, 16))
result_mat4$density <- result_mat4$mean_freq/result_mat4$total_window_size

df для размера окна 6

result_mat5 <- data.frame( window_size= rep("6",16), 
                      combined_cols= c(rep("1_2_3_4_5_6",16)),
                      row_names= c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"),
                      freq=c(4,2,1,1,3,1,1,1,1,1,2,2,1,1,3,1),
                      mean_freq=(c(4,2,1,1,3,1,1,1,1,1,2,2,1,1,3,1)/5), 
                      total_window_size= rep(471, 16))
result_mat5$density <- result_mat5$mean_freq/result_mat5$total_window_size

Finalфрейм данных с результатами для всех субкадров данных вместе взятых

result_df <- rbind(result_mat1, result_mat2, result_mat3, result_mat4, result_mat5)    

Мне нужна помощь, чтобы применить эти 4 функции к каждому элементу списка и вывести результаты в один фрейм данных.

1 Ответ

1 голос
/ 20 сентября 2019

Вот начало.Я не уверен, как combined_cols должен быть добавлен к каждому data.frame, так как он имеет другой размер (кажется, каждый длиннее, чем все остальные столбцы data.frame.) Я не уверен, все лиэти вычисления абсолютно правильны, но это, по крайней мере, демонстрирует суть вопроса «как перебрать список, собрать некоторые фреймы данных с результатами и объединить их в один большой фрейм данных.)

myList <- lapply(seq_len(ncol(mat) - 1), function(j) do.call(cbind, lapply(seq_len(ncol(mat) - j), function(i) rowSums(mat[, i:(i + j)]))))
myListOutput <- list()

for (i in 1:length(myList)) {
  print(i)
  myMat = myList[[i]]

  freq <- rowSums(myMat)
  window_size = rep(as.character(i + 1), length(freq))
  # your final data sample shows dividing by 5 on each one, 
  # but your pseudo code shows something to do with the columns
  mean_freq <- rowSums(myMat)/(ncol(myMat))  
  total_window_size <- rep((i+1)*pi*25, length(freq))
  density <- mean_freq/total_window_size

  myDf = data.frame(window_size, freq, mean_freq, total_window_size, density)

  myListOutput[[i]] <- myDf 

}

result_df = do.call(rbind, myListOutput)
...