2015-01-15 2 views
1

Firt всего позвольте мне создать некоторые тестовые данные:Стек все столбцы в две колонки с категорическим колонки в R

dat <- data.frame(Model_A=rnorm(10, 10), Model_B=rnorm(10, 12), Data_A=rnorm(10, 11), 
Data_B=rnorm(10, 13)) 

# this produces the following 
dat 

    Model_A Model_B Data_A Data_B 
1 10.421684 13.201037 11.711313 13.18555 
2 9.529258 11.086655 12.015787 14.13989 
3 9.483633 10.697859 10.123176 15.50154 
4 10.623490 11.171480 9.406222 12.56696 
5 10.460739 10.925262 10.640612 11.98662 
6 9.351494 10.276617 11.717629 13.00709 
7 10.264206 11.587463 10.653878 13.33615 
8 10.183569 13.187894 10.127552 13.87615 
9 8.832003 9.739279 10.970686 13.26850 
10 10.932207 11.974472 10.374939 12.11782 

То, что я хочу быть в состоянии сделать это «стек» все столбцы в два колонок, называемых «Модель» и «Данные». С столбцами, содержащими каждую уникальную комбинацию как отдельных столбцов «Модель», так и «Данные». Я также хотел бы создать индексный столбец, который классифицирует данные. Набор данных Я хотел бы создать это:

Cat    Model  Data 
Model_A_Data_A 10.421684 11.711313 
Model_A_Data_A 9.529258 12.015787 
Model_A_Data_A 9.483633 10.123176 
Model_A_Data_A 10.62349 9.406222 
Model_A_Data_A 10.460739 10.640612 
Model_A_Data_A 9.351494 11.717629 
Model_A_Data_A 10.264206 10.653878 
Model_A_Data_A 10.183569 10.127552 
Model_A_Data_A 8.832003 10.970686 
Model_A_Data_A 10.932207 10.374939 
Model_A_Data_B 10.421684 13.18555 
Model_A_Data_B 9.529258 14.13989 
Model_A_Data_B 9.483633 15.50154 
Model_A_Data_B 10.62349 12.56696 
Model_A_Data_B 10.460739 11.98662 
Model_A_Data_B 9.351494 13.00709 
Model_A_Data_B 10.264206 13.33615 
Model_A_Data_B 10.183569 13.87615 
Model_A_Data_B 8.832003 13.2685 
Model_A_Data_B 10.932207 12.11782 
Model_B_Data_A 13.201037 11.711313 
Model_B_Data_A 11.086655 12.015787 
Model_B_Data_A 10.697859 10.123176 
Model_B_Data_A 11.17148 9.406222 
Model_B_Data_A 10.925262 10.640612 
Model_B_Data_A 10.276617 11.717629 
Model_B_Data_A 11.587463 10.653878 
Model_B_Data_A 13.187894 10.127552 
Model_B_Data_A 9.739279 10.970686 
Model_B_Data_A 11.974472 10.374939 
Model_B_Data_B 13.201037 13.18555 
Model_B_Data_B 11.086655 14.13989 
Model_B_Data_B 10.697859 15.50154 
Model_B_Data_B 11.17148 12.56696 
Model_B_Data_B 10.925262 11.98662 
Model_B_Data_B 10.276617 13.00709 
Model_B_Data_B 11.587463 13.33615 
Model_B_Data_B 13.187894 13.87615 
Model_B_Data_B 9.739279 13.2685 
Model_B_Data_B 11.974472 12.11782 

Я думаю, что он должен быть в состоянии сделать с некоторыми из инструментов в пакете перекроить, но я не могу понять, как получить индекс столбца там со всеми уникальные комбинации столбцов «Модель» и «Данные».

Стоит отметить, что мой фактический набор данных имеет 9 колонок «Модель» и 15 столбцов «Данные».

спасибо.

+0

Ваш желаемый выход соответствует предоставленному набору данных? –

+0

А я только что понял, что где-то долго, как я сгенерировал данные, чтобы создать желаемый результат, моя ошибка. Я исправлю это сейчас. –

ответ

1

Это также можно soution:

dat <- data.frame(Model_A=rnorm(10, 10), Model_B=rnorm(10, 12), Data_A=rnorm(10, 11), 
       Data_B=rnorm(10, 13)) 
model.names <- grep("Model",names(dat),value=TRUE) 
data.names <- grep("Data",names(dat),value=TRUE) 

new.dat <- 
lapply(model.names,function(m) { 
    lapply(data.names,function(d) { 
    md <- cbind(dat[,m],dat[,d]) 
    md.name <- rep(paste0(m,"_",d),nrow(md)) 
    data.frame(md.name,md) 
    }) 
}) 

new.dat <- do.call(rbind,lapply(new.dat,function(l) do.call(rbind,l))) 
names(new.dat) <- c("Cat","Model","Data") 

Во-первых, он извлекает имена моделей и столбцы данных. Aferwards, используя дважды в два раза, создает кадр данных для каждой комбинации модели и данных, помещая соответствующее имя в первый столбец. Последний шаг состоит в том, чтобы поместить все эти кадры данных, находящиеся внутри двукратного вложенного списка, в единый кадр данных.

+0

Это работает, спасибо! –

1

Вы можете попробовать на

  1. Создания комбинации «имена столбцов» (combn(colnames...))
  2. Удалить имена из «INDX», которые принадлежат к тому же типу (то есть. Data_A, Данные, или Model_A, Model_B)
  3. Subset "INDX" создать "indx2"
  4. split "indx2" на "столбцы", чтобы создать список ("ЛСТ")
  5. Изменение названия из "ЛСТ" в определить группу («Cat»)
  6. Подмножество «dat» на основе «lst» имен и используйте unnest от tidyr, чтобы перечеркнуть элементы списка.

    library(tidyr) 
    indx <- combn(colnames(dat),2) 
    indx1 <- apply(indx, 2, function(x) length(unique(sub('_.*', '', x)))>1) 
    indx2 <- indx[,indx1] 
    lst <- split(indx2, col(indx2)) 
    names(lst) <- apply(indx2, 2, paste, collapse='_') 
    
    res <- unnest(lapply(lst,function(x) { 
           x1 <- dat[x] 
           colnames(x1) <- c('Model', 'Data') 
           x1}), Cat) 
    head(res,2) 
    #   Cat  Model  Data 
    #1 Model_A_Data_A 9.676133 9.491202 
    #2 Model_A_Data_A 11.599942 10.446249 
    

Или вы могли бы использовать expand.grid вместе с rbindlist из data.table

indx <- expand.grid(split(colnames(dat), 
        sub("_.*", '', colnames(dat))))[2:1] 
    indx1 <- transform(indx, Cat=paste(Model, Data, sep="_")) 

    library(data.table) 
    res1 <- rbindlist(apply(indx1, 1, function(x) { 
       x1 <- unname(x) 
       data.frame(Cat=x1[3],dat[x1[1:2]])})) 
+0

Спасибо за отличное решение. Он почти присутствует, но не содержит категориального столбца «Кошка», но мне нужно идентифицировать разные комбинации столбцов. –

+0

@Catchment_Jack Пожалуйста, уточните обновление – akrun

+0

Спасибо, теперь это работает. Я собираюсь дать @Stibu ответ, потому что он работает исключительно на базовых функциях. –

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