Альтернатива expand.grid для data.frames

У меня есть data.frame df и я хочу, чтобы каждая строка в этом df дублировала lengthTime раз и добавляла новый столбец, который насчитывает от 1 до lengthTime для каждой строки в df .

Я знаю, это звучит довольно сложно, но в основном я хочу применить expand.grid к df . Вот уродливое обходное решение, и у меня возникает ощущение, что наиболее простое решение (возможно, даже функция base-R?):

 df <- data.frame(ID = rep(letters[1:3], each=3), CatA = rep(1:3, times = 3), CatB = letters[1:9]) lengthTime <- 3 nrRow <- nrow(df) intDF <- df for (i in 1:(lengthTime - 1)) { df <- rbind(df, intDF) } df$Time <- rep(1:lengthTime, each=nrRow) 

Я думал, что могу просто использовать expand.grid(df, 1:lengthTime) , но это не работает. outer тоже не принесла удачи. Так кто-нибудь знает хорошее решение?

Почему не просто что-то вроде df[rep(1:nrow(df),times = 3),] чтобы расширить кадр данных, а затем добавить дополнительный столбец так же, как вы уже выше, с df$Time <- rep(1:lengthTime, each=nrRow) ?

Прошло некоторое время, так как этот вопрос был опубликован, но я недавно наткнулся на него, ища только что в названии, а именно: expand.grid который работает для фреймов данных. Опубликованные ответы касаются более конкретного вопроса OP, поэтому, если кто-то ищет более общее решение для фреймов данных, вот несколько более общий подход:

 expand.grid.df <- function(...) Reduce(function(...) merge(..., by=NULL), list(...)) # For the example in the OP expand.grid.df(df, data.frame(1:lengthTime)) # More generally df1 <- data.frame(A=1:3, B=11:13) df2 <- data.frame(C=51:52, D=c("Y", "N")) df3 <- data.frame(E=c("+", "-")) expand.grid.df(df1, df2, df3) 

Вы также можете просто выполнить merge используя NULL качестве столбца слияния (что приведет к merge для простой репликации комбинаторных данных):

 data.frame(time=1:lengthTime) %>% merge(iris, by=NULL) 

Оператор трубопроводов %>% поступает из пакета magrittr ( dplyr также автоматически присоединяет его) и просто использовался для улучшения удобочитаемости. Вы также можете просто merge(iris, data.frame(...), by=NULL)

Быстрое обновление

Существует также функция cross () в пакете tidyr, которая может использоваться вместо слияния, несколько быстрее и возвращает tbl_df / tibble.

 data.frame(time=1:10) %>% merge(iris, by=NULL) data.frame(time=1:10) %>% tidyr::crossing(iris) 

Это работает:

 REP <- rep(1:nrow(df), 3) df2 <- data.frame(df[REP, ], Time = rep(1:3, each = 9)) rownames(df2) <- NULL df2 

Решение data.table :

 > library(data.table) > ( df <- data.frame(ID = rep(letters[1:3], each=3), + CatA = rep(1:3, times = 3), + CatB = letters[1:9]) ) ID CatA CatB 1 a 1 a 2 a 2 b 3 a 3 c 4 b 1 d 5 b 2 e 6 b 3 f 7 c 1 g 8 c 2 h 9 c 3 i > ( DT <- data.table(df)[, lapply(.SD, function(x) rep(x,3))][, Time:=rep(1:3, each=nrow(df0))] ) ID CatA CatB Time 1: a 1 a 1 2: a 2 b 1 3: a 3 c 1 4: b 1 d 1 5: b 2 e 1 6: b 3 f 1 7: c 1 g 1 8: c 2 h 1 9: c 3 i 1 10: a 1 a 2 11: a 2 b 2 12: a 3 c 2 13: b 1 d 2 14: b 2 e 2 15: b 3 f 2 16: c 1 g 2 17: c 2 h 2 18: c 3 i 2 19: a 1 a 3 20: a 2 b 3 21: a 3 c 3 22: b 1 d 3 23: b 2 e 3 24: b 3 f 3 25: c 1 g 3 26: c 2 h 3 27: c 3 i 3 

Еще один :

 > library(data.table) > ( df <- data.frame(ID = rep(letters[1:3], each=3), + CatA = rep(1:3, times = 3), + CatB = letters[1:9]) ) > DT <- data.table(df) > rbindlist(lapply(1:3, function(i) cbind(DT, Time=i))) ID CatA CatB Time 1: a 1 a 1 2: a 2 b 1 3: a 3 c 1 4: b 1 d 1 5: b 2 e 1 6: b 3 f 1 7: c 1 g 1 8: c 2 h 1 9: c 3 i 1 10: a 1 a 2 11: a 2 b 2 12: a 3 c 2 13: b 1 d 2 14: b 2 e 2 15: b 3 f 2 16: c 1 g 2 17: c 2 h 2 18: c 3 i 2 19: a 1 a 3 20: a 2 b 3 21: a 3 c 3 22: b 1 d 3 23: b 2 e 3 24: b 3 f 3 25: c 1 g 3 26: c 2 h 3 27: c 3 i 3 
  • Как узнать R как язык программирования?
  • Тест anova терпит неудачу на lme fits, созданный с помощью вставленной формулы
  • R: преобразовать строку с разделителями в переменные
  • R - вырезание с помощью заданного интервала
  • R усиливает местный охват
  • Удалите повторяющиеся пары столбцов, сортируйте строки на основе двух столбцов
  • определить параметр $ right с переменной в R
  • Сплит-кадр данных по уровням фактора и именных кадров данных по этим уровням
  • Какой самый полезный трюк?
  • Импорт текстового файла в виде отдельной символьной строки
  • Найдите, сколько раз повторяющиеся строки повторяются в кадре данных R
  • Давайте будем гением компьютера.