Как использовать применить семью к

Это может быть вопрос о применении / вопрос об управлении данными / их комбинация. Я относительно новичок в R и активно приспосабливаюсь к тому, как управлять данными в R и Stata (в качестве примера). Я много читал, но не нашел хорошего примера того, как (1) извлекать векторы из кадра данных по группам; (2) применить функцию попарно ко всем комбинациям этих векторов; и (3) вывести результаты в виде матрицы, поэтому я спрашиваю вас всех, как это сделать. Я упростил все имена переменных/данные в примере ниже:

У меня есть dataframe df, структурированный следующим образом:

id score1 score2 extravar1 extravar2 .....
1     10      9        a   1.4345124      
1      9      7        b   1.1133529
1      5      5        c   -0.1712851
2      4      4        d   -0.4924446
2      3      2     junk   -0.8136040
2      6      6     junk   0.14987444
3      5      6     junk   0.14331245
etc

Мне нужно создать ковариационную матрицу подмножеств ID score1 и ID score2. Другими словами, я хотел бы выполнить следующие вычисления как для score1, так и для score2:

cov(vector of df$score1 for id 1 only,df$score1 for id 1 only) 
cov(vector of df$score1 for id 1 only,df$score1 for id 2 only)
cov(vector of df$score1 for id 1 only,df$score1 for id 3 only)
.
.
.
cov(vector of df$score1 for id 1 only,df$score1 for id 288 only)
cov(vector of df$score1 for id 1 only,df$score1 for id 289 only)
cov(vector of df$score1 for id 2 only,df$score1 for id 1 only) 
cov(vector of df$score1 for id 2 only,df$score1 for id 2 only)
.
.
.
cov(vector of df$score1 for id 289 only,df$score1 for id 288 only)
cov(vector of df$score1 for id 289 only,df$score1 for id 289 only)

и я хотел бы, чтобы данные выводились в два (один перед score1, один для score2) списков, фреймов данных или матриц, которые выглядят так (где s1-1 - это вектор score1 для id = 1):

         1               2               3       ...    288           289
1  cov(s1-1,s1-1)  cov(s1-1,s1-2) cov(s1-1,s1-3)   cov(s1-1,s1-288)   cov(s1-1,s1-289)
2  cov(s1-2,s1-1)  cov(s1-2,s1-2) cov(s1-2,s1-3)   cov(s1-2,s1-288)   cov(s1-2,s1-289)
3  cov(s1-3,s1-1)  cov(s1-3,s1-2) cov(s1-3,s1-3)   cov(s1-3,s1-288)   cov(s1-3,s1-289)
.
.
.
288 cov(s1-288,s1-1)  cov(s1-288,s1-2) cov(s1-288,s1-3) cov(s1-288,s1-288) cov(s1-288,s1-289)
289 cov(s1-289,s1-1)  cov(s1-289,s1-2) cov(s1-289,s1-3) cov(s1-289,s1-288) cov(s1-289,s1-289)

Моя проблема в том, что я сталкиваюсь с проблемами (1) манипулирования данными, чтобы они были в правильном формате для такого анализа и (2) решения, какие из функций применения будут наиболее подходящими для использования (может быть, mapply?). В настоящее время я использую split для разделения данных на группы, но не знаю, как манипулировать ими оттуда:

df.scores <- df[,c("id","score1","score2")]
databy.id <- split(df.scores,df.scores$id)

Что дает список, я не на 100% понимаю, как манипулировать при применении. head(databy.id) выглядит примерно так:

$`1`
           id score1      score2 
1           1     10           9 
2           1      9           7 
3           1      5           5 
4           1      4           4 
5           1      3           2 
...

$`2`
           id score1      score2 
1           2      8           3 
2           2      9           2 
3           2     10           1 
4           2      9           3 
5           2      4           9 
...

$`3`
           id score1      score2 
1           3      8           7 
2           3      3           4 
3           3      2           3 
4           3      4           6 
5           3      6           1 
...

Я могу (и уже) решить это с помощью циклов, но предпочел бы этого не делать, так как мне нужно многократно рандомизировать оценки и моделировать/сохранять множество таких матриц (что занимает слишком много времени с помощью циклов). Должен ли я использовать ddply, mapply или какие-то другие функции? Есть ли у вас какие-либо предложения о том, как действовать дальше?


person j.m.sappenfield    schedule 20.02.2015    source источник


Ответы (1)


Я узнал, что функция cov принимает матрицы. Я выяснил, как преобразовать все ID-векторы оценок в матрицу, используя цикл, и таким образом вычисляю ковариационную матрицу. Однако это неэлегантное решение, и я уверен, что есть лучший способ инициализировать фрейм данных, который я использую (где ids — это вектор всех id:

vectors.score1 <- data.frame("1"=databy.id[[1]]$score1)
for (j in 2:length(ids)) {
  vectors.score1[,toString(ids[j])] <- databy.id[[j]]$score1  
}
covariances <- cov(vectors.score1,vectors.score1)
colnames(covariances) <- ids  

Мне было бы интересно более элегантное решение для изменения формы данных, если оно у кого-то есть.

Изменить: исправлено название переменной Impact ==> score1.

person j.m.sappenfield    schedule 20.02.2015
comment
Кажется, это не относится к вашему вопросу. В вопросе нет упоминания об ударе. - person IRTFM; 21.02.2015