2012-05-01 2 views
1

Как я могу преобразовать data.frame ниже в матрицу, как указано? первые два столбца data.frame содержат переменные строк, все комбинации других столбцов (кроме тех, которые содержат значения) определяют столбцы. В идеале я ищу решение, которое не требует дополнительных пакетов (так нетreshape2 решение). Также нет решения ftable.Как преобразовать data.frame в (плоскую) матрицу?

(df <- data.frame(c1=rep(c(1, 2), each=8), c2=rep(c(1, 2, 1, 2), each=4), 
        gr=rep(c(1, 2), 8), subgr=rep(c(1,2), 4, each=2), val=1:16)) 

c1 c2 gr1.subgr1 gr1.subgr2 gr2.subgr1 gr2.subgr2 
1 1 1   3   2   4 
1 2 5   7   6   8 
2 1 9   11   10   12 
2 2 13   15   14   16 
+0

всегда есть базовая функция 'reshape', я никогда не был достаточно умен, чтобы понять аргументы к нему, но я также не обжора для боли, поэтому я обычно использую 'reshape2' для его согласованности и простоты использования. YMMV – Chase

+0

reshape и reshape2 записаны в базе R, поэтому, если вы хотите использовать их подход, не загружая пакет, просто извлеките содержимое функции (например, введите acast и скопируйте содержимое функции) –

+1

Почему избежать пакетов? –

ответ

3

Используйте переменные взаимодействия для построения групп:

newdf <- reshape(df, idvar=1:2, direction="wide", 
      timevar=interaction(df$gr,df$subgr) , 
      v.names="val", 
      drop=c("gr","subgr")) 
names(newdf)[3:6] <- c("gr1.subgr1", "gr1.subgr2", "gr2.subgr1", "gr2.subgr2") 
newdf 
    c1 c2 gr1.subgr1 gr1.subgr2 gr2.subgr1 gr2.subgr2 
1 1 1   1   2   3   4 
5 1 2   5   6   7   8 
9 2 1   9   10   11   12 
13 2 2   13   14   15   16 
+0

+1 - не видел/Я забыл о 'взаимодействии()'. Вероятно, гораздо лучший маршрут, чем его создание вручную. – Chase

+0

Это работает, спасибо DWin. Я построил его в своей оригинальной проблеме. У меня есть data.frame точно такого же типа (как показано 'str()'). Проблема в том, что я получаю «Ошибка в' [.data.frame' (data,, timevar): undefined columns selected', не уверен, что не так ... –

+0

Можете ли вы сделать эту ошибку с небольшим подмножеством, а затем опубликовать dput output? (Я только что запустил его на новом сеансе и не получил никаких ошибок). –

2

Хорошо, это похоже на то, что вы хотите. От чтения файла справки, это кажется, что это должен делать то, что вы хотите:

reshape(df, idvar = c("c1", "c2"), timevar = c("gr", "subgr") 
     , direction = "wide") 
    c1 c2 val.c(1, 2, 1, 2) val.c(1, 1, 2, 2) 
1 1 1    NA    NA 
5 1 2    NA    NA 
9 2 1    NA    NA 
13 2 2    NA    NA 

Я не могу полностью объяснить, почему он показывает со значениями NA. Однако, может быть, это немного со страницы справки объясняет:

timevar 
the variable in long format that differentiates multiple records from the same 
group or individual. If more than one record matches, the first will be taken. 

я сначала принял это означает, что R будет использовать это частичные возможности сопоставления, если существует неопределенность в именах столбцов вы дали, но, может быть, нет? Затем я попытался комбинируя gr и subgr в одну колонку:

df$newcol <- with(df, paste("gr.", gr, "subgr.", subgr, sep = "")) 

И давайте попробуем это снова:

reshape(df, idvar = c("c1", "c2"), timevar = "newcol" 
     , direction = "wide", drop= c("gr","subgr")) 

    c1 c2 val.gr.1subgr.1 val.gr.2subgr.1 val.gr.1subgr.2 val.gr.2subgr.2 
1 1 1    1    2    3    4 
5 1 2    5    6    7    8 
9 2 1    9    10    11    12 
13 2 2    13    14    15    16 

Presto! Я не могу объяснить или понять, как сделать это не append val. именам столбцов, но я оставлю вас понять это самостоятельно. Я уверен, что это где-то на странице справки. Он также поставил группы в другом порядке, чем вы просили, но данные кажутся правильными.

FWIW, вот решение с reshape2

> dcast(c1 + c2 ~ gr + subgr, data = df, value.var = "val") 
    c1 c2 1_1 1_2 2_1 2_2 
1 1 1 1 3 2 4 
2 1 2 5 7 6 8 
3 2 1 9 11 10 12 
4 2 2 13 15 14 16 

Хотя вы все еще должны очистить имена столбцов.

+0

Интересно! Я использовал метод 'paste (« grp »,« subgrp »)' to 'reshape()' в мои ранние дни R и думал, что это кажется странным. Вы убедили меня, что я не сумасшедший, и что я, вероятно, должен научиться использовать 'reshape2' вместо этого. – thelatemail

+0

Версия с 'dcast' действительно хороша. Можно также использовать 'acast'. –

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