Извлечь информацию из условной формулы - PullRequest
7 голосов
/ 11 марта 2010

Я хотел бы написать функцию R, которая принимает формулу в качестве первого аргумента, аналогично lm () или glm () и friends. В данном случае это функция, которая берет фрейм данных и записывает файл в формате SVMLight , который имеет такую ​​общую форму:

<line> .=. <target> <feature>:<value> <feature>:<value> ... <feature>:<value> # <info>
<target> .=. +1 | -1 | 0 | <float> 
<feature> .=. <integer> | "qid"
<value> .=. <float>
<info> .=. <string>

например, следующий фрейм данных:

  result qid     f1     f2     f3     f4   f5     f6     f7     f8
1     -1   1 0.0000 0.1253 0.0000 0.1017 0.00 0.0000 0.0000 0.9999
2     -1   1 0.0098 0.0000 0.0000 0.0000 0.00 0.0316 0.0000 0.3661
3      1   1 0.0000 0.0000 0.1941 0.0000 0.00 0.0000 0.0509 0.0000
4     -1   2 0.0000 0.2863 0.0948 0.0000 0.34 0.0000 0.7428 0.0608
5      1   2 0.0000 0.0000 0.0000 0.4347 0.00 0.0000 0.9539 0.0000
6      1   2 0.0000 0.7282 0.9087 0.0000 0.00 0.0000 0.0000 0.0355

будет выглядеть следующим образом:

-1 qid:1 2:0.1253 4:0.1017 8:0.9999
-1 qid:1 1:0.0098 6:0.0316 8:0.3661
1  qid:1 3:0.1941 7:0.0509
-1 qid:2 2:0.2863 3:0.0948 5:0.3400 7:0.7428 8:0.0608
1  qid:2 4:0.4347 7:0.9539
1  qid:2 2:0.7282 3:0.9087 8:0.0355

Функция, которую я хотел бы написать, будет называться примерно так:

write.svmlight(result ~ f1+f2+f3+f4+f5+f6+f7+f8 | qid, data=mydata, file="out.txt")

Или даже

write.svmlight(result ~ . | qid, data=mydata, file="out.txt")

Но я не могу понять, как использовать model.matrix() и / или model.frame(), чтобы знать, какие столбцы он должен писать. Это правильные вещи, на которые стоит посмотреть?

Любая помощь высоко ценится!

Ответы [ 2 ]

4 голосов
/ 12 марта 2010

Частичный ответ. Вы можете подписать объект формулы, чтобы получить дерево разбора формулы:

> f<-a~b+c|d
> f[[1]]
`~`
> f[[2]]
a
> f[[3]]
b + c | d
> f[[3]][[1]]
`|`
> f[[3]][[2]]
b + c
> f[[3]][[3]]
d

Теперь все, что вам нужно, это код для обхода этого дерева.

ОБНОВЛЕНИЕ: Вот пример функции, которая обходит дерево.

walker<-function(formu){
  if (!is(formu,"formula"))
    stop("Want formula")
  lhs <- formu[[2]]
  formu <- formu[[3]]

  if (formu[[1]]!='|')
    stop("Want conditional part")

  condi <- formu[[3]]

  flattener <- function(f) {if (length(f)<3) return(f);
                            c(Recall(f[[2]]),Recall(f[[3]]))}
  vars <- flattener(formu[[2]])

  list(lhs=lhs,condi=condi,vars=vars)
}

walker(y~a+b|c)

Также посмотрите документацию для terms.formula и terms.object. Глядя на код для некоторых функций, которые принимают условные формулы, может помочь, например. функция lmer в пакете lme4.

0 голосов
/ 12 марта 2010

Я использовал

formu.names <- all.vars(formu)
Y.name <- formu.names[1]
X.name <- formu.names[2]
block.name <- formu.names[3]

В коде, который я написал о выполнении пост-hoc для теста Фридмана:

http://www.r -statistics.com / 2010/02 / ретроспективный-анализ-для-Фридманов тест-р-код / ​​

Но это будет работать только для: Y`X | block

Я надеюсь на лучший ответ, который дадут другие.

...