2013-05-16 7 views
6

In R, l'oggetto formula è simbolico e sembra piuttosto difficile da analizzare. Tuttavia, devo analizzare tale formula in un insieme esplicito di etichette per uso al di fuori di R.Uso di R per interpretare una formula simbolica per uso esterno

(1)

Lasciando f rappresento la model formulae in cui una risposta non è specificato, ad esempio ~V1 + V2 + V3, una cosa che ho provato era:

t <- terms(f) 
attr(t, "term.labels") 

Tuttavia, questo non ottiene che cosa è esattamente esplicito se alcune delle variabili in f sono categorica. Ad esempio, sia V1 una variabile categoriale con 2 categorie, ad esempio un valore booleano, e sia V2 una doppia.

Pertanto, un modello specificato da ~V1:V2 deve avere 2 parametri: "intercetta" e "xyes: z". Nel frattempo, un modello specificato da ~V1:V2 - 1 deve avere i parametri "xno: z" e "xyes: z". Tuttavia, senza un modo di dire alla funzione terms() quali variabili sono categoriali (e quante categorie) non ha modo di essere in grado di interpretarle. Invece, ha solo V1:V2 nei suoi "terms.labels" che non significa nulla nel contesto che V1 è categoriale.

(2)

D'altra parte, utilizzando model.matrix è un modo facile per ottenere esattamente quello che voglio. Il problema è che richiede un argomento data, il che è un problema per me perché voglio solo un'interpretazione esplicita della formula simbolica per l'uso al di fuori di R. Questo metodo per farlo sprecherà molto tempo (comparativamente) perché R deve leggere i dati da una fonte esterna quando tutto ciò che è veramente necessario sapere per la formula è quali variabili sono categoriali (e quante categorie) e quali variabili sono doppie.

C'è un modo per utilizzare 'model.matrix' con solo specificando i tipi di dati, piuttosto che i dati effettivi? Se no, cos'altro è una soluzione praticabile?

risposta

4

Bene, è solo nel contesto di avere dati che è possibile determinare se una determinata variabile è un fattore o un valore numerico. Quindi non puoi farlo senza l'argomento dati. Ma tutto ciò di cui hai bisogno è la struttura, non i dati stessi, quindi puoi usare una cornice dati a 0 righe con le colonne di tutti i tipi giusti.

f <- ~ V1:V2 
V1numeric <- data.frame(V1=numeric(0), V2=numeric(0)) 
V1factor <- data.frame(V1=factor(c(), levels=c("no","yes")), V2=numeric(0)) 

Guardando i due data.frames:

> V1numeric 
[1] V1 V2 
<0 rows> (or 0-length row.names) 
> str(V1numeric) 
'data.frame': 0 obs. of 2 variables: 
$ V1: num 
$ V2: num 
> V1factor 
[1] V1 V2 
<0 rows> (or 0-length row.names) 
> str(V1factor) 
'data.frame': 0 obs. of 2 variables: 
$ V1: Factor w/ 2 levels "no","yes": 
$ V2: num 

Usa model.matrix con questi

> model.matrix(f, data=V1numeric) 
    (Intercept) V1:V2 
attr(,"assign") 
[1] 0 1 
> model.matrix(f, data=V1factor) 
    (Intercept) V1no:V2 V1yes:V2 
attr(,"assign") 
[1] 0 1 1 
attr(,"contrasts") 
attr(,"contrasts")$V1 
[1] "contr.treatment" 

Se si dispone di un set di dati reali, è facile da ottenere un 0-fila data.frame da ciò che conserva le informazioni sulla colonna. Basta iscriversi con FALSE. Non hai bisogno di costruire manualmente data.frame se ne hai uno con le proprietà giuste.

> str(mtcars) 
'data.frame': 32 obs. of 11 variables: 
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... 
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ... 
$ disp: num 160 160 108 258 360 ... 
$ hp : num 110 110 93 110 175 105 245 62 95 123 ... 
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... 
$ wt : num 2.62 2.88 2.32 3.21 3.44 ... 
$ qsec: num 16.5 17 18.6 19.4 17 ... 
$ vs : num 0 0 1 1 0 1 0 1 1 1 ... 
$ am : num 1 1 1 0 0 0 0 0 0 0 ... 
$ gear: num 4 4 4 3 3 3 3 4 4 4 ... 
$ carb: num 4 4 1 1 2 1 4 2 2 4 ... 
> str(mtcars[FALSE,]) 
'data.frame': 0 obs. of 11 variables: 
$ mpg : num 
$ cyl : num 
$ disp: num 
$ hp : num 
$ drat: num 
$ wt : num 
$ qsec: num 
$ vs : num 
$ am : num 
$ gear: num 
$ carb: num 
+0

Grazie per la risposta rapida. Ho un vero set di dati, ma è grande e al di fuori di R quindi leggerlo è ciò che riduce l'efficienza. Quello che hai nella prima parte sembra ottimo, ma una cosa che non capisco è che 'model.matrix (f, data = V1Factor)' produce 3 parametri rilevanti, quando non dovrebbe avere 'V1no: V2' come è un'intercettazione. –

+0

R è riluttante a rimuovere i parametri di ordine inferiore quando sono presenti interazioni, forse questo è il motivo: http://stackoverflow.com/q/11335923/289572 – Henrik

+0

@JonClaus Penso che dovrebbe avere tre parametri: l'intercetta, la pendenza di 'V2' quando' V1' è no, e la pendenza di 'V2' quando' V1' è sì (il modo in cui è parametrizzato qui). Si potrebbero anche ottenere 3 parametri con un'intercetta, una pendenza di 'V2' quando' V1' è no, e il cambiamento nella pendenza di 'V2' quando' V1' cambia da no a sì. Comunque lo parametrizzi, ci sono 3 parametri. –