Генерация матрицы возрастающих значений через каждые 2 строки без цикла for в R

Я пытаюсь создать эту матрицу без использования цикла for (чтобы ускорить время обработки):

       Module 1 Module 2 Module 3
y0       20       20       20
y1       20       20       20
y0       40       40       40
y1       40       40       40
y0       60       60       60
y1       60       60       60
y0       80       80       80
y1       80       80       80
y0      100      100      100
y1      100      100      100
y0      120      120      120
y1      120      120      120
y0      140      140      140
y1      140      140      140
y0      160      160      160
y1      160      160      160
y0      180      180      180
y1      180      180      180
y0      200      200      200
y1      200      200      200

Я пытался применить функции, replicate() и do.call(). Я закончил с этим кодом:

a = 10          # Number of increments
n1 = 100       # Sample size
m.fn <- function(n1, a) {
  b <- matrix(rep(n1), nrow = 2, ncol = 3)
  rownames(b) <- c("y0", "y1")
  c <- do.call(rbind, replicate(a, b, simplify=FALSE))

  colnames(c) <- c("Module 1", "Module 2", "Module 3")
  return(c)
}

Что создает матрицу, аналогичную приведенной выше, но со всеми элементами как 20.

Я попытался заменить значения с небольшим успехом, как показано ниже:

 a = 10          # Number of increments
 n1 = 100       # Sample size
    m.fn <- function(n1, a) {
      b <- matrix(rep(n1), nrow = 2, ncol = 3)
      rownames(b) <- c("y0", "y1")
      c <- do.call(rbind, replicate(a, b, simplify=FALSE))
      c[3:(2 * a),] <- (n1 * seq(3, 2 * a))
      colnames(c) <- c("Module 1", "Module 2", "Module 3")
      return(c)
    }

Вот что получается:

       Module 1 Module 2 Module 3
y0       20       20       20
y1       20       20       20
y0       60       60       60
y1       80       80       80
y0      100      100      100
y1      120      120      120
y0      140      140      140
y1      160      160      160
y0      180      180      180
y1      200      200      200
y0      220      220      220
y1      240      240      240
y0      260      260      260
y1      280      280      280
y0      300      300      300
y1      320      320      320
y0      340      340      340
y1      360      360      360
y0      380      380      380
y1      400      400      400

Для справки, это код, который я использовал для создания желаемой матрицы с использованием цикла for:

    n.fn <- function(n1, a) {
  b <- matrix(rep(1, 3), nrow = 1, ncol = 3)
  for (no in 1:a) {
    c <- matrix(rep(n1 * no, 6), nrow = 2, ncol = 3)
    rownames(c) <- c("y0", "y1")
    b <- rbind(b, c)
  }
  b <- as.matrix(b[-1, 1:3])
  colnames(b) <- c("Module 1", "Module 2", "Module 3")
  return(b)
}
n <- n.fn(n1, a)

Будем признательны за любую помощь в создании первой матрицы без использования цикла for!


person MBorg    schedule 07.11.2017    source источник
comment
Спасибо за ваш ответ. Это не работает для меня. Я получаю ответ: › replicate(3, lapply(seq(20, 200, 20), rep, 2) %›% unlist) Ошибка в lapply(seq(20, 200, 20), rep, 2) %›% unlist: не удалось найти функцию %›%   -  person MBorg    schedule 07.11.2017
comment
Вам нужно загрузить установку и использовать библиотеку dplyr, чтобы использовать канал. Или просто запустите replicate(3, unlist(lapply(seq(20,200,20), rep, 2) )). Yay для кронштейна в изобилии!   -  person Adam Quek    schedule 07.11.2017
comment
Спасибо Адам. Теперь %›% работает, и ваш код работает отлично. И он генерирует список, который мне нужен!   -  person MBorg    schedule 07.11.2017


Ответы (1)


Вы можете просто сгенерировать последовательность от 20 до 400, повторить ее столько раз, сколько раз столбцов и расположить в матрице:

 df <- matrix(rep(rep(seq(from = 20, to = 400, by = 20), each = 2), times = 3), ncol = 3)

Другой способ - по предложению Адама Квека с использованием реплики:

df <- replicate(3, unlist(lapply(seq(20,200,20), rep, 2) )) 

Теперь просто дайте ему желаемые имена столбцов и строк:

colnames(df) <- paste("Module", 1:ncol(df))
rownames(df) <- rep(paste0("y", 0:1), nrow(df)/2)
person missuse    schedule 07.11.2017
comment
Спасибо за ваш ответ. Это создает фрейм/матрицу данных, но не тот, который мне нужен. Я кадр/матрица данных, которая имеет 2 строки по 20, затем 2 строки по 40. Каждая 1-я строка называется y0, а каждая 2-я строка называется y1. Я включил его вверху моего исходного поста. Ваше предложение, хотя и полезное, каждый раз генерирует строки из 20 по возрастанию, а имена - y1, y2, y3 и т. д. - person MBorg; 07.11.2017
comment
@Matthew Borg проверьте редактирование, пожалуйста, надеюсь, я решил проблему - person missuse; 07.11.2017
comment
Спасибо миссисус. Ваше предложение и правки сработали великолепно! Я также ценю, что вы вернулись, чтобы отредактировать свое предложение! - person MBorg; 07.11.2017