Должен ли ddply использовать все возможные комбинации переменных разделения или только наблюдаемые?

У меня есть фрейм данных под названием thetas, содержащий около 2,7 миллиона наблюдений.

> str(thetas)
'data.frame':   2700000 obs. of  8 variables:
 $ rho_cnd   : num  0 0 0 0 0 0 0 0 0 0 ...
 $ pct_cnd   : num  0 0 0 0 0 0 0 0 0 0 ...
 $ sx        : num  1 2 3 4 5 6 7 8 9 10 ...
 $ model     : Factor w/ 7 levels "dN.mN","dN.mL",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ estTheta  : num  -1.58 -1.716 0.504 -2.296 0.98 ...
 $ trueTheta : num  0.0962 -3.3913 3.6006 -0.1971 2.1906 ...
 $ estError  : num  -1.68 1.68 -3.1 -2.1 -1.21 ...
 $ trueAberSx: num  0 0 0 0 0 0 0 0 0 0 ...

Я хотел бы использовать ddply или какую-то аналогичную функцию для суммирования ошибки оценки (столбец estError в моем фрейме данных), но где суммы находятся в каждом условии моей симуляции. Проблема в том, что у меня нет простого способа объединить значения из других столбцов этого фрейма данных, чтобы однозначно идентифицировать все эти условия. Чтобы быть более конкретным: столбец model содержит 7 возможных значений. Три из этих возможных значений сопоставляются только с одним возможным значением в каждом из rho_cnd и pct_cnd, а остальные четыре возможных значения model сопоставляются с 6 возможными парами значений в rho_cnd и pct_cnd.

Я знаю, что очевидным решением было бы вернуться назад и создать переменную, которая однозначно идентифицирует все условия, которые мне нужно было бы определить здесь, чтобы работал следующий код:

> sums <- ddply(thetas,.(condition1,condition2,etc.),sum(estError))

Но я просто не хочу возвращаться и воссоздавать, как построен этот фрейм данных. Прямо сейчас у меня есть два фрейма данных, созданных с двумя отдельными вызовами expand.grid, которые затем rbinded и сортируются для создания фрейма данных со списком всех допустимых условий, но даже если бы я сохранил эти несколько строк кода, я не уверен, как ссылаться на них с ddply. Я бы предпочел даже не использовать это решение, но при необходимости буду.

> conditions 
   models rhos pcts
1   dN.mN  0.0 0.00
2   dN.mL  0.0 0.00
3   dN.mH  0.0 0.00
4   dL.mN  0.1 0.01
12  dL.mN  0.1 0.02
20  dL.mN  0.1 0.10
8   dL.mN  0.2 0.01
16  dL.mN  0.2 0.02
24  dL.mN  0.2 0.10
5   dL.mL  0.1 0.01
13  dL.mL  0.1 0.02
21  dL.mL  0.1 0.10
9   dL.mL  0.2 0.01
17  dL.mL  0.2 0.02
25  dL.mL  0.2 0.10
6   dH.mN  0.1 0.01
14  dH.mN  0.1 0.02
22  dH.mN  0.1 0.10
10  dH.mN  0.2 0.01
18  dH.mN  0.2 0.02
26  dH.mN  0.2 0.10
7   dH.mH  0.1 0.01
15  dH.mH  0.1 0.02
23  dH.mH  0.1 0.10
11  dH.mH  0.2 0.01
19  dH.mH  0.2 0.02
27  dH.mH  0.2 0.10

Любые советы по улучшению кода и/или большей эффективности? Спасибо!


person psychometriko    schedule 03.05.2013    source источник
comment
Я запутался. Почему ddply(thetas,.(model,rho_cnd,pct_cnd),...) не работает?   -  person joran    schedule 03.05.2013
comment
@joran Вы правы - я предполагал, что, как и expand.grid(), использование того, что вы предлагаете, приведет к ddply объединению вместе всех возможных комбинаций трех индикаторов состояния моих столбцов, а не использованию только фактических/наблюдаемых пар. Я только что проверил это, и вы правы, что это работает.   -  person psychometriko    schedule 04.05.2013


Ответы (1)


Я согласен с комментарием, что ddply(thetas,.(model,rho_cnd,pct_cnd),...) должен работать. Если определенные комбинации этих переменных не отображаются, ddply(..., .drop=TRUE) гарантирует, что ненаблюдаемые комбинации не будут отображаться.

Однако, если вы хотите, чтобы ddply не просматривал некоторые из несуществующих комбинаций, вы можете попробовать что-то вроде следующего:

#newCond <- apply(thetas[,c("model", "rho_cnd", "pct_cnd")], 1, paste, collapse="_")
newCond <- do.call(paste, thetas[,c("model", "rho_cnd", "pct_cnd")], sep="_") #as suggested by baptiste
thetas2 <- cbind(thetas, newCond)

Я допускаю, что приведенный выше код может работать медленно для вас, поэтому я не уверен, что это то, что вам нужно. Но оттуда вы сможете использовать ddply() с .variables=newCond.

Кроме того, поскольку вы возвращаете только одно число для каждого подмножества данных, вы можете просто использовать агрегат, если хотите.

sums <- aggregate(thetas2[,"estError"], by=thetas2[,"newCond"], colSums)

Надеюсь, это поможет.

person rbatt    schedule 04.05.2013
comment
вам не нужно применять; вставка векторизована (что-то вроде do.call(paste, theta[,...]) должно делать) - person baptiste; 04.05.2013
comment
Мне это не подходит: (1)test <- matrix(1:15, ncol=3) (2)apply(test, 1, paste, collapse="_") (3)do.call(paste, list(t(test), collapse="_")) Они не одинаковы. Как заставить его работать? - person rbatt; 04.05.2013
comment
он работает со списком, таким как data.frame, do.call(paste, c(as.data.frame(test), sep="_")) - person baptiste; 04.05.2013
comment
Ах, здорово! Спасибо за совет :) - person rbatt; 04.05.2013
comment
@rbatt Да, вы оба правы, Джоран, что это работает. Спасибо, что указали на это! - person psychometriko; 04.05.2013