我有一个带有响应变量Y和三个因子的数据框,'factor.a','factor.b'和'factor.c'
我正在尝试编写一个
的函数如果因素的所有级别相同,则从数据框中删除列
当一个因子的多个级别,最多5个级别时,将术语'beta.factor.x [1..n]'添加到参数向量中。
从列表中排除参数beta.factor.b [1](已修复)
这是我的代码。我认为它看起来很好并且运行良好,但我已经读过最好避免嵌套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=''))
}
}
}
}
答案 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
,具体取决于你从你的功能返回。)