можно ли избежать этих вложенных циклов? - PullRequest
1 голос
/ 04 ноября 2010

У меня есть фрейм данных с переменной ответа Y и тремя факторами: factor.a, factor.b и factor.c

Я пытаюсь написать функцию

  1. удалит столбцы из фрейма данных, если все уровни фактора одинаковы

  2. добавит термин "beta.factor".x [1..n] 'к вектору параметров при наличии более одного уровня фактора, до 5 уровней.

  3. исключить параметр beta.factor.b [1] из списка (это исправлено)

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

data <- data.frame(       y = c(1,2,3,4),
                   factor.a = c(1, 1, 2, 1),
                   factor.b = c(1, 2, 2, 3),
                   factor.c = c(0, 0, 0, 0))

model.parms <- list(factor.a  = length(unique(data$factor.a)),
                    factor.b  = length(unique(data$factor.b)),
                    factor.c  = length(unique(data$factor.c)))
vars <- 'beta.o'
for (x in c('factor.a','factor.c', 'factor.b')) {
  if(model.parms[[x]] == 1) {
    data <- data[, -which(names(data) == x)]
  } else {
    m <- min(model.parms[[x]], 5)
    for (i in 1:m) {
      if(!i == 1 && x == 'factor.b') {
        vars <- c(vars, paste('beta.', x, '[', i, ']', sep=''))
      }
    }
  }
}

Ответы [ 2 ]

2 голосов
/ 05 ноября 2010

Вам вообще не нужны петли

vars <- c('beta.o',
  paste('sd.', names(model.parms)[model.parms > 1], sep = ''),
  paste('beta.factor.b', '[', 1 +  seq_len(min(model.parms[["factor.b"]], 5) - 1), ']', sep='')
)
data <- data[, names(model.parms)[model.parms > 1]]
1 голос
/ 06 ноября 2010

Вы можете часто аннулировать вложенные циклы с помощью by (). Взяв свой фрейм данных,

> out <- by(data,data[,-1],identity)
> out

получит вас

factor.a: 1
factor.b: 1
factor.c: 0
  y factor.a factor.b factor.c
1 1        1        1        0
------------------------------------------------------------ 
factor.a: 2
factor.b: 1
factor.c: 0
NULL
------------------------------------------------------------ 
factor.a: 1
factor.b: 2
factor.c: 0
  y factor.a factor.b factor.c
2 2        1        2        0
------------------------------------------------------------ 
factor.a: 2
factor.b: 2
factor.c: 0
  y factor.a factor.b factor.c
3 3        2        2        0
------------------------------------------------------------ 
factor.a: 1
factor.b: 3
factor.c: 0
  y factor.a factor.b factor.c
4 4        1        3        0
------------------------------------------------------------ 
factor.a: 2
factor.b: 3
factor.c: 0
NULL

если вы unclass(out), вы получите матрицу или массив режима list; каждый элемент будет содержать строки исходного фрейма данных, агрегированные по уровням, указанным во втором аргументе by(). Конечно, вы можете заменить функцию identity другой функцией, которая работает с этим подмножеством фрейма данных (вывод всегда будет матрицей или массивом, но не обязательно режима list, в зависимости от того, что вы возвращаете из функция).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...