我试图重写我的代码,不包含任何for循环或ifelse循环。目的是根据变量 mu 和变量 cinterval 提取包含0和1的矩阵 - 如果y0落在其第95个CI内,则生成1,并且0 y0落在它的第95个CI,同样适用于y1。对于许多模块,y0和y1都会重复这一过程。
mu 包含y0和y1的值; cinterval 包含四行:
- y0
的第95个CI限制- y0
的第95个CI限制- y1
的第95个CI限制- y1的第95个CI限制
醇>
cinterval 可以编程为具有任意数量的模块:
cinterval.fn <- function(y0y1modules) {
matrix(c(y0results, y1results) nrow=4, ncol=no.of.modules, byrow=T) #simplified from true code
rownames(cinterval) <- c("y0 95LCI", "y0 95UCI", "y1 95LCI", "y1 95UCI")
colnames(cinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
return(cinterval)
}
> cinterval
module.1 module.2 module.3
y0 95LCI 2.434602 1.784056 1.751713
y0 95UCI 5.988160 6.519465 6.833455
y1 95LCI 3.778811 2.681708 2.805293
y1 95UCI 9.228941 9.716476 10.258412
mu 看起来像这样:
mu <- c(4, 8)
mu
y0 y1
4 8
我的代码是:
incinterval.fn <- function(cov.xy, mu, n1, dr) {
cinterval <- cintervaloutput.fn(cov.xy, mu, n1, dr) # Generates matrix with 95% CI values for y0 and y1 after modules
y0 <- NULL # Empty vector
for (module.no in 1:ncol(cinterval)) {
y0 <- cbind(y0, ifelse (cinterval[1, module.no] <= mu["y0"] || mu["y0"] <= cinterval[2, module.no], 1, 0))
} # If y0 inside CI, 1, else 0
y1 <- NULL # Empty vector
for (module.no in 1:ncol(cinterval)) {
y1 <- cbind(y1, ifelse (cinterval[3, module.no] <= mu["y1"] || mu["y1"] <= cinterval[4, module.no], 1, 0))
} # If y1 inside CI, 1, else 0
incinterval <- rbind(y0, y1) # Combines vectors
colnames(incinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
return(incinterval)
}
结果,incinterval,如下所示:
module.1 module.2 module.3
[y0] 1 1 1
[y1] 1 1 1
任何有关更高效编码以替换和ifelse的帮助将不胜感激!我目前使用2 for和ifeelse循环。
答案 0 :(得分:1)
示例数据:
as.numeric(mu["y0"] >= cinterval[1,] & mu["y0"] <= cinterval[2,])
[1] 1 1 1
您可以利用矢量化并将单个值与矢量
进行比较{{1}}
相应地为&#34; y1&#34;。
工作答案 1 :(得分:0)
假设输入数据的创建类似于:
mu = c(y0 = 4, y1 = 8)
cinterval <-
data.frame(names = c("y0", "y0", "y1", "y1"),
CI = c("LCI", "UCI", "LCI", "UCI"),
module.1 = c(2.434602, 5.988160, 3.778811, 9.228941),
module.2 = c(1.784056, 6.519465, 2.681708, 9.716476),
module.3 = c(1.751713, 6.833455, 2.805293, 10.258412))
然后这样的事情可能会做你想要的事情:
sapply(seq_along(mu),
function(y) {
cis <- cinterval[cinterval[["names"]] == names(mu)[y], -1:-2]
apply(cis, 2, function(ci) {
findInterval(mu[y], ci)
})
})
答案 2 :(得分:0)
我不确定您对数据结构的依赖程度,但我提出了不同的方法。
如果您以其他格式构建数据集,则可以轻松地将incinterval
的结果写入其他变量。
新数据:
cinterval <- data.frame(year = c(0, 0, 0, 1, 1, 1),
LCI = c(2.434602, 1.784056, 1.751713, 3.778811, 2.681708, 2.805293),
UCI = c(5.988160, 6.519465, 6.833455, 9.228941, 9.716476, 10.258412),
module = c(1, 2, 3, 1, 2, 3)
)
> cinterval
year LCI UCI module
1 0 2.434602 5.988160 1
2 0 1.784056 6.519465 2
3 0 1.751713 6.833455 3
4 1 3.778811 9.228941 1
5 1 2.681708 9.716476 2
6 1 2.805293 10.258412 3
现在定义mu
mu <- c("y0" = 4, "y1" = 8)
使用apply
为您的行添加和ifelse
一个简短的findInterval
条件,以获得包含结果的新列:
cinterval$inCI <- apply(cinterval, 1,
function(x) ifelse(x[1] == 0, findInterval(mu["y0"], x[2:3]),
findInterval(mu["y1"], x[2:3]))
)
你的输出:
year LCI UCI module inCI
1 0 2.434602 5.988160 1 1
2 0 1.784056 6.519465 2 1
3 0 1.751713 6.833455 3 1
4 1 3.778811 9.228941 1 1
5 1 2.681708 9.716476 2 1
6 1 2.805293 10.258412 3 1
请注意,如果findInterval
值低于CI,mu
将返回0,如果它在其中,则返回1,如果它高于CI,则返回2。
在处理许多years
时,这可能会变得很麻烦,但要包含尽可能多的modules
非常强大。
答案 3 :(得分:0)
感谢大家的建议和反馈。
我接受了Ape的建议,因为这是最简单的。
现在,代码现在用粗体文本更改为:
incinterval.fn <- function(cov.xy, mu, n1, dr) {
cinterval <- cintervaloutput.fn(cov.xy, mu, n1, dr) # Generates matrix with 95% CI values for y0 and y1 after treatment modules (can be any number of modules))
**incinterval <- rbind(as.numeric(mu["y0"] >= cinterval[1,] & mu["y0"] <= cinterval[2,]),
as.numeric(mu["y1"] >= cinterval[3,] & mu["y0"] <= cinterval[4,]))**
colnames(incinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
return(incinterval)
}
不是使用for循环和ifelse循环,而是使用更简单的方法来回答问题,并使用比较运算符生成向量。