Изменить форму фрейма данных с широкого на панельный с несколькими переменными и некоторой неизменностью во времени

Это основная проблема анализа данных, которую Stata решает за один шаг.

Создайте широкий фрейм данных с постоянными во времени данными (x0) и изменяющимися во времени данными за 2000 и 2005 годы (x1,x2):

d1 <- data.frame(subject = c("id1", "id2"),  
x0 = c("male", "female"),  
x1_2000 = 1:2,   
x1_2005 = 5:6,  
x2_2000 = 1:2,  
x2_2005 = 5:6    
) 

s.t.

subject x0 x1_2000 x1_2005 x2_2000 x2_2005  
1     id1 male         1       5       1       5  
2     id2 female       2       6       2       6  

Я хочу сформировать его как панель, чтобы данные выглядели так:

        subject     x0 time x1 x2
1     id1   male 2000  1  1
2     id2 female 2000  2  2
3     id1   male 2005  5  5
4     id2 female 2005  6  6

Я могу сделать это с reshape с.т.

d2 <-reshape(d1, 
idvar="subject",
varying=list(c("x1_2000","x1_2005"),
    c("x2_2000","x2_2005")),
    v.names=c("x1","x2"),
    times = c(2000,2005),
    direction = "long",
    sep= "_")

Меня больше всего беспокоит то, что когда у вас есть десятки переменных, приведенная выше команда становится очень длинной. В stata можно было бы просто ввести:

reshape long x1 x2, i(subject) j(year)

Есть ли такое простое решение в R?


person Fred    schedule 13.03.2011    source источник


Ответы (2)


reshape может угадать многие его аргументы. В этом случае достаточно указать следующее. Пакеты не используются.

 reshape(d1, dir = "long", varying = 3:6, sep = "_")

давая:

       subject     x0 time x1 x2 id
1.2000     id1   male 2000  1  1  1
2.2000     id2 female 2000  2  2  2
1.2005     id1   male 2005  5  5  1
2.2005     id2 female 2005  6  6  2
person G. Grothendieck    schedule 13.03.2011
comment
Хороший! Но что происходит, когда переменные имеют имена samplesep=2000 и т. д. Можно ли более точно определить значение параметра sep=? - person Fred; 14.03.2011
comment
@Fred, используйте аргумент split вместо sep, то есть reshape(d1, dir = "long", varying = 3:6, split = list(regexp = "_2", include = TRUE)), или уменьшите этот случай до того, который указан в вопросе, то есть reshape(setNames(d1, sub("sample_", "", names(d1))), dir = "long", varying = 3:6, sep = "_") - person G. Grothendieck; 14.03.2011

вот краткий пример использования пакета reshape2:

library(reshape2)
library(stringr)

# it is always useful to start with melt
d2 <- melt(d1, id=c("subject", "x0"))

# redefine the time and x1, x2, ... separately
d2 <- transform(d2, time = str_replace(variable, "^.*_", ""),
                    variable = str_replace(variable, "_.*$", ""))

# finally, cast as you want
d3 <- dcast(d2, subject+x0+time~variable)

теперь вам даже не нужно указывать x1 и x2.
Этот код работает, если переменные увеличиваются:

> d1 <- data.frame(subject = c("id1", "id2"), x0 = c("male", "female"),
+ x1_2000 = 1:2,
+ x1_2005 = 5:6,
+ x2_2000 = 1:2,
+ x2_2005 = 5:6,
+ x3_2000 = 1:2,
+ x3_2005 = 5:6,
+ x4_2000 = 1:2,
+ x4_2005 = 5:6
+ ) 
> 
> d2 <- melt(d1, id=c("subject", "x0"))
> d2 <- transform(d2, time = str_replace(variable, "^.*_", ""),
+                     variable = str_replace(variable, "_.*$", ""))
> 
> d3 <- dcast(d2, subject+x0+time~variable)
> 
> d3
  subject     x0 time x1 x2 x3 x4
1     id1   male 2000  1  1  1  1
2     id1   male 2005  5  5  5  5
3     id2 female 2000  2  2  2  2
4     id2 female 2005  6  6  6  6
person kohske    schedule 13.03.2011
comment
Спасибо, это полезно. Не очень понятно, что делает transform (файл справки не очень полезен) и как интерпретировать "^.*_" и "_.*$". Я спрашиваю, потому что некоторые переменные на самом деле называются sampletransform2000 и т. д. - person Fred; 13.03.2011
comment
Может быть, это более интуитивно понятно с данными за год с именем sampletemp1 <- transform(temp, time = str_sub(variable, -4), variable = str_sub(variable, 1,str_length(variable)-5))2000 и т. д.: temp1 <- transform(temp, time = str_sub(variable, -4), variable = str_sub(variable, 1,str_length(variable)-5)) - person Fred; 13.03.2011
comment
@Fred это зависит от формата имени переменной. если длина (хотя бы части) символа фиксирована, ваш путь проще. в противном случае регулярное выражение является более гибким. - person kohske; 13.03.2011