2017-01-20 2 views
1

Хотелось бы создать новый кадр данных в R, который принимает набор строк, и объединяет каждый вариант в nrow * nrow * ncol.STEM: Создайте последовательные комбинации каждой строки в R

library(dplyr) 
dat <- read.table(text = 
     " Animal Color Size 
      Cat Orange 10 
      Dog Black 20", header=TRUE) 

Хотел этот вывод:

Animal Color Size 
Cat  NA  NA 
Cat  Orange NA 
Cat  Orange 10 
Dog  NA  NA 
Dog  Black NA 
Dog  Black 20 

Есть функция в R, которые могут сделать это - что-то вроде expand.grid?

expand.grid(dat$Animal, dat$Color, dat$Size) %>% arrange(Var1, Var2, Var3) #Note: this does not give the correct answer. 

Я могу создать первый кусок из Дат это первая строка с помощью:

dat <- c("Cat", "Orange", 10) 

counter <- 1 
datInner <- list() 
for(i in 1:length(dat)){ # loops through 3x 

    # i <- 3 
    datInner[[i]] <- dat[1:i] 
    counter <- counter + 1 

} 

library(plyr) 
# Adapted from http://stackoverflow.com/questions/17308551/do-callrbind-list-for-uneven-number-of-column 
plyr::rbind.fill(lapply(datInner, function(y){as.data.frame(t(y), 
      stringsAsFactors = FALSE)})) 

    # V1  V2 V3 
    # 1 Cat <NA> <NA> 
    # 2 Cat Orange <NA> 
    # 3 Cat Orange 10 

ПРИМЕЧАНИЕ: Будет ли вызывать эту функцию введите Последовательная Tree Extended Matrix (STEM). Он берет таблицу с деревом, где глубина узлов изменяется, перечисляя только конечные узлы и преобразуя их в таблицу со всеми последовательными комбинациями дерева.

+0

Откуда взялись 'NA'? 'expand.grid' не вставляет' NA '. – alistaire

+0

NA - это просто заполнители – eyeOfTheStorm

+0

Почему в колонке 'Animal' нет' NA '? – Gregor

ответ

0

Оказывается, что цикл может решить эту проблему со списком намного легче, чем я первоначально думал, и это обобщать для новичков с различными глубинами узлов. Это та же скорость, что и превосходный ответ Джоэля с примером двух строк. Однако в настоящее время это можно распараллелить для гораздо более быстрого чтения за пределами использования Matrix. Примечание. Для Joel и моего собственного ответа здесь потребуется unique, если существуют разные глубины узлов - например, NA вместо 20 значений в таблице dat.

library(dplyr) 
datInner <- list() 
for(i in 1:ncol(dat)){ datInner[[i]] <- dat[1:i] }; # foreach %dopar% for parallel 
datInner %>% bind_rows 
2

Решение dplyr - не очень общее.

library(dplyr) 
rbind(
    dat %>% 
    group_by(Animal) %>% 
    summarize(Color = NA, Size = NA) %>% 
    ungroup(), 
    dat %>% 
    group_by(Animal, Color) %>% 
    summarize(Size = NA) %>% 
    ungroup(), 
    dat) %>% arrange(Animal) 

# Animal Color Size 
#1 Cat <NA> NA 
#2 Cat Orange NA 
#3 Cat Orange 10 
#4 Dog <NA> NA 
#5 Dog Black NA 
#6 Dog Black 20 
+0

В духе этого вопроса, учитывая, что ваш ответ с dplyr, я дам вам галочку для того, чтобы сделать это адаптируемым к изменяющейся среде столбцов. Как бы то ни было, похоже, что пользователю нужно будет добавить несколько дополнительных команд 'group_by' с определенными именами каждого столбца. – eyeOfTheStorm

1

должно быть много эффективных ответов, чем это, это просто попытка!

m <- t(sapply(1:ncol(dat), function(i) c(1:i, rep(NA, (ncol(dat)-i))))) 
m 
#  [,1] [,2] [,3] 
#[1,] 1 NA NA 
#[2,] 1 2 NA 
#[3,] 1 2 3 

#2. now i apply each row to original data (dat) Basically performing subset 
m1 <- apply(dat, 1, function(i) apply(m, 1, function(j) i[j])) 
data.frame(matrix(m1, byrow = T, ncol = ncol(dat))) 
# X1  X2 X3 
#1 Cat <NA> <NA> 
#2 Cat Orange <NA> 
#3 Cat Orange 10 
#4 Dog <NA> <NA> 
#5 Dog Black <NA> 
#6 Dog Black 20 

Примечание: последний столбец является factor из-за наличия его в matrix

+1

Большое использование вложенных 'apply's – eyeOfTheStorm

 Смежные вопросы

  • Нет связанных вопросов^_^