英文:
How can I use function or loop to simplify my program?
问题
1.3(The values needed to create Lo-Mendell-Rubin likelihood ratio test) and 1.4(Calculate Lo-Mendell-Rubin likelihood ratio test p-value) 步骤的程序可以使用循环和函数来简化。以下是简化后的代码:
# 1.3 使用函数和循环简化
lca_models <- list(lca1, lca2, lca3, lca4)
lca_ll <- lca_param <- lca_classes <- numeric(length(lca_models))
for (i in 1:4) {
lca_ll[i] <- lca_models[[i]]$llik
lca_param[i] <- lca_models[[i]]$npar
lca_classes[i] <- length(lca_models[[i]]$P)
}
n <- lca1$Nobs
# 1.4 使用函数和循环简化
calc_lrt_for_k <- function(k) {
calc_lrt(n, lca_ll[k - 1], lca_param[k - 1], lca_classes[k - 1],
lca_ll[k], lca_param[k], lca_classes[k])
}
lrt_results <- sapply(2:4, calc_lrt_for_k)
clutabletest <- as.data.frame(t(as.data.frame(lrt_results)))
这段代码首先将1.3 中的值提取到向量中,并使用循环创建 1.4 中所需的 LRT 结果。最后,将结果存储在 clutabletest
中。
英文:
everyone
I am doing this:
# LCA data
library(poLCA)
data("carcinoma")
f <- f <- cbind(A, B, C ,D ,E, F, G) ~ 1
#1.1 Create LCA model k=1~4
lc <-list()
for(i in 1:4){
lc[[i]] <- poLCA(f, carcinoma, nclass=i)
}
#1.2 Separate list
lca1 <- lc[[1]]
lca2 <- lc[[2]]
lca3 <- lc[[3]]
lca4 <- lc[[4]]
#1.3 The values needed to create Lo-Mendell-Rubin likelihood ratio test
lca1_ll <- lca1$llik #k=1
lca1_param <- lca1$npar
lca1_classes <- length(lca1$P)
lca2_ll <- lca2$llik #k=2
lca2_param <- lca2$npar
lca2_classes <- length(lca2$P)
lca3_ll <- lca3$llik #k=3
lca3_param <- lca3$npar
lca3_classes <- length(lca3$P)
lca4_ll <- lca4$llik #k=4
lca4_param <- lca4$npar
lca4_classes <- length(lca4$P)
n <- lca1$Nobs
library(tidyLPA)
#1.4 Calculate Lo-Mendell-Rubin likelihood ratio test p-value
calc_k12 <-
calc_lrt(n,
lca1_ll, lca1_param, lca1_classes, # k-1
lca2_ll, lca2_param, lca2_classes) # k
calc_k23 <-
calc_lrt(n,
lca2_ll, lca2_param, lca2_classes, # k-1
lca3_ll, lca3_param, lca3_classes) # k
calc_k34 <-
calc_lrt(n,
lca3_ll, lca3_param, lca3_classes, # k-1
lca4_ll, lca4_param, lca4_classes) # k
clutabletest <- as.data.frame(cbind(calc_k12, calc_k23, # Create table
calc_k34))
clutabletest <- as.data.frame(t(clutabletest))
How can i use function or loop to simplify the program of 1.3(The values needed to create Lo-Mendell-Rubin likelihood ratio test) and 1.4(Calculate Lo-Mendell-Rubin likelihood ratio test p-value) steps.
Thank you!
答案1
得分: 1
以下是您要翻译的内容:
First, use `lapply`.
lc <- lapply(1:4, \(i) poLCA::poLCA(f, carcinoma, nclass=i, verbose=0))
Then loop over `lc` with `sapply`,
t(sapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
}))
# lr lmr_lr df lmr_p
# [1,] 414.41596 387.35127 8 9.496374e-79
# [2,] 47.10372 44.02747 8 5.622002e-07
# [3,] 2.42389 2.26559 8 9.717677e-01
or to get the rownames:
lapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
`rownames<-`(t(lrt), sprintf('%s:%s', i, i + 1))
}) |> do.call(what=rbind)
# lr lmr_lr df lmr_p
# 1:2 414.41596 387.35127 8 9.496374e-79
# 2:3 47.10372 44.02747 8 5.622002e-07
# 3:4 2.42389 2.26559 8 9.717677e-01
EDIT:
If you do that often, you could wrap it all in a function:
fun <- \(f, data, n) {
lc <- lapply(seq_len(n), \(i) poLCA::poLCA(f, data, nclass=i, verbose=0))
tests <- lapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
`rownames<-`(t(lrt), sprintf('%s:%s', i, i + 1))
})
do.call('rbind', tests)
}
fun(f, carcinoma, n=4)
# lr lmr_lr df lmr_p
# 1:2 414.415961 387.35127 8 9.496374e-79
# 2:3 47.103717 44.02747 8 5.622002e-07
# 3:4 4.880175 4.56146 8 8.032532e-01
----
*Data:*
data("carcinoma")
f <- cbind(A, B, C, D, E, F, G) ~ 1
请注意,我已经将HTML实体代码(如 <
和 >
)转换为正常的标签,以便更好地理解和使用。
英文:
First, use lapply
.
lc <- lapply(1:4, \(i) poLCA::poLCA(f, carcinoma, nclass=i, verbose=0))
Then loop over lc
with sapply
,
t(sapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
}))
# lr lmr_lr df lmr_p
# [1,] 414.41596 387.35127 8 9.496374e-79
# [2,] 47.10372 44.02747 8 5.622002e-07
# [3,] 2.42389 2.26559 8 9.717677e-01
or to get the rownames:
lapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
`rownames<-`(t(lrt), sprintf('%s:%s', i, i + 1))
}) |> do.call(what=rbind)
# lr lmr_lr df lmr_p
# 1:2 414.41596 387.35127 8 9.496374e-79
# 2:3 47.10372 44.02747 8 5.622002e-07
# 3:4 2.42389 2.26559 8 9.717677e-01
EDIT:
If you do that often, you could wrap it all in a function:
fun <- \(f, data, n) {
lc <- lapply(seq_len(n), \(i) poLCA::poLCA(f, data, nclass=i, verbose=0))
tests <- lapply(seq_along(lc)[-length(lc)], \(i) {
lrt <- tidyLPA::calc_lrt(lc[[i]]$Nobs, lc[[i]]$llik, lc[[i]]$npar, length(lc[[i]]$P),
lc[[i + 1]]$llik, lc[[i + 1]]$npar, length(lc[[i + 1]]$P))
`rownames<-`(t(lrt), sprintf('%s:%s', i, i + 1))
})
do.call('rbind', tests)
}
fun(f, carcinoma, n=4)
# lr lmr_lr df lmr_p
# 1:2 414.415961 387.35127 8 9.496374e-79
# 2:3 47.103717 44.02747 8 5.622002e-07
# 3:4 4.880175 4.56146 8 8.032532e-01
Data:
data("carcinoma")
f <- cbind(A, B, C, D, E, F, G) ~ 1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论