Повторить data.frame N раз

У меня есть следующий фрейм данных

data.frame(a = c(1,2,3),b = c(1,2,3)) ab 1 1 1 2 2 2 3 3 3 

и я хочу превратить его в

  ab 1 1 1 2 2 2 3 3 3 4 1 1 5 2 2 6 3 3 7 1 1 8 2 2 9 3 3 

или повторить N раз. Есть ли простая функция для этого в R? Благодаря!

EDIT: обновлен до лучшего современного R-ответа.

Вы можете использовать replicate() , а затем rbind результат. Имена ростов автоматически изменяются для запуска от 1: ноль.

 d <- data.frame(a = c(1,2,3),b = c(1,2,3)) n <- 3 do.call("rbind", replicate(n, d, simplify = FALSE)) 

Более традиционный способ - использовать индексирование, но здесь изменение розового имени не совсем так аккуратно (но более информативно):

  d[rep(seq_len(nrow(d)), n), ] 

Ниже приведены усовершенствования, описанные выше, первые два с использованием функционального программирования purrr, идиоматический purrr:

 purrr::map_df(seq_len(3), ~d) 

и менее идиоматический purrr (идентичный результат, хотя и более неудобный):

 purrr::map_df(seq_len(3), function(x) d) 

и, наконец, с помощью индексации, а не списка, используйте dplyr :

 d %>% slice(rep(row_number(), 3)) 

Для объектов data.frame это решение в несколько раз быстрее, чем @ mdsummer и @ wojciech-sobala’s.

 d[rep(seq_len(nrow(d)), n), ] 

Для объектов data.table @ mdsummer немного быстрее, чем применение выше, после преобразования в data.frame . Для больших n это может переворачиваться. microbenchmark ,

Полный код:

 packages <- c("data.table", "ggplot2", "RUnit", "microbenchmark") lapply(packages, require, character.only=T) Repeat1 <- function(d, n) { return(do.call("rbind", replicate(n, d, simplify = FALSE))) } Repeat2 <- function(d, n) { return(Reduce(rbind, list(d)[rep(1L, times=n)])) } Repeat3 <- function(d, n) { if ("data.table" %in% class(d)) return(d[rep(seq_len(nrow(d)), n)]) return(d[rep(seq_len(nrow(d)), n), ]) } Repeat3.dt.convert <- function(d, n) { if ("data.table" %in% class(d)) d <- as.data.frame(d) return(d[rep(seq_len(nrow(d)), n), ]) } # Try with data.frames mtcars1 <- Repeat1(mtcars, 3) mtcars2 <- Repeat2(mtcars, 3) mtcars3 <- Repeat3(mtcars, 3) checkEquals(mtcars1, mtcars2) # Only difference is row.names having ".k" suffix instead of "k" from 1 & 2 checkEquals(mtcars1, mtcars3) # Works with data.tables too mtcars.dt <- data.table(mtcars) mtcars.dt1 <- Repeat1(mtcars.dt, 3) mtcars.dt2 <- Repeat2(mtcars.dt, 3) mtcars.dt3 <- Repeat3(mtcars.dt, 3) # No row.names mismatch since data.tables don't have row.names checkEquals(mtcars.dt1, mtcars.dt2) checkEquals(mtcars.dt1, mtcars.dt3) # Time test res <- microbenchmark(Repeat1(mtcars, 10), Repeat2(mtcars, 10), Repeat3(mtcars, 10), Repeat1(mtcars.dt, 10), Repeat2(mtcars.dt, 10), Repeat3(mtcars.dt, 10), Repeat3.dt.convert(mtcars.dt, 10)) print(res) ggsave("repeat_microbenchmark.png", autoplot(res)) 

Пакет dplyr содержит функцию bind_rows() которая напрямую объединяет все кадры данных в списке, так что нет необходимости использовать do.call() вместе с rbind() :

 df <- data.frame(a = c(1, 2, 3), b = c(1, 2, 3)) library(dplyr) bind_rows(replicate(3, df, simplify = FALSE)) 

Для большого количества bind_rows() также намного быстрее, чем rbind() :

 library(microbenchmark) microbenchmark(rbind = do.call("rbind", replicate(1000, df, simplify = FALSE)), bind_rows = bind_rows(replicate(1000, df, simplify = FALSE)), times = 20) ## Unit: milliseconds ## expr min lq mean median uq max neval cld ## rbind 31.796100 33.017077 35.436753 34.32861 36.773017 43.556112 20 b ## bind_rows 1.765956 1.818087 1.881697 1.86207 1.898839 2.321621 20 a 
 d <- data.frame(a = c(1,2,3),b = c(1,2,3)) r <- Reduce(rbind, list(d)[rep(1L, times=3L)]) 

Просто используйте простую индексацию с функцией повтора.

 mydata<-data.frame(a = c(1,2,3),b = c(1,2,3)) #creating your data frame n<-10 #defining no. of time you want repetition of the rows of your dataframe mydata<-mydata[rep(rownames(mydata),n),] #use rep function while doing indexing rownames(mydata)<-1:NROW(mydata) #rename rows just to get cleaner look of data 
  • Обновление кадра данных с помощью функции не работает
  • импортировать файл dat в R
  • как заменить одиночную обратную косую черту в R
  • Как я могу извлечь диапазоны осей для объекта ggplot2?
  • Выберите только первые строки для каждого уникального значения столбца в R
  • Создание фильма из серии сюжетов в R
  • как читать данные в формате utf-8 в R?
  • Выберите NA в таблице данных в R
  • qplot ggplot не выполняется при поиске
  • Как объединить факторы, не превращая их в целые уровни?
  • Объединить много кадров данных из файлов csv, когда подразумевается столбец идентификатора?
  • Давайте будем гением компьютера.