我能避免这些嵌套的for循环吗?

时间:2010-11-04 20:26:12

标签: r performance for-loop

我有一个带有响应变量Y和三个因子的数据框,'factor.a','factor.b'和'factor.c'

我正在尝试编写一个

的函数
  1. 如果因素的所有级别相同,则从数据框中删除列

  2. 当一个因子的多个级别,最多5个级别时,将术语'beta.factor.x [1..n]'添加到参数向量中。

  3. 从列表中排除参数beta.factor.b [1](已修复)

  4. 这是我的代码。我认为它看起来很好并且运行良好,但我已经读过最好避免嵌套for循环,所以我很好奇是否有更有效的方法。

    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 个答案:

答案 0 :(得分:2)

您根本不需要任何循环

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 :(得分:1)

您经常可以使用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,具体取决于你从你的功能返回。)