R:在 functions/loops(Extreme Bounds 包)中使用过滤器命令解决列表深处的对象
R: Adress objects deep inside lists with filter commands inside functions/loops (ExtremeBounds package)
我正在使用 ExtremeBounds 包,它提供了一个多级列表,其中(除其他外)数据帧处于最低级别。我 运行 这个包超过了几个规范,我想在这些结果中收集一些选定数据框的列。这些应该按规范(下例中的 spec1 和 spec2)收集并排列在数据帧列表中。然后可以将此数据框列表用于各种用途,例如将不同规范的结果导出到不同的 Excel 表格中。
这是一些创建有问题对象的代码(只是 运行 盲目地使用这段代码,我的问题只涉及如何处理它创建的列表类型:eba_results ):
library("ExtremeBounds")
Data <- data.frame(var1=rbinom(30,1,0.2),var2=rbinom(30,2,0.2),
var3=rnorm(30),var4=rnorm(30),var5=rnorm(30))
spec1 <- list(y=c("var1"),
freevars=c("var2"),
doubtvars=c("var3","var4"))
spec2 <- list(y=c("var1"),
freevars=c("var2"),
doubtvars=c("var3","var4","var5"))
indicators <- c("spec1","spec2")
ebaFun <- function(x){
eba <- eba(data=Data, y=x$y,
free=x$freevars,
doubtful=x$doubtvars,
reg.fun=glm, k=1, vif=7, draws=50, weights = "lri", family = binomial(logit))}
eba_results <- lapply(mget(indicators),ebaFun) #eba_results is the object in question
手动我知道如何访问每个元素,例如:
eba_results$spec1$bounds$type #look at str(eba_results) to see the different levels
所以 "bounds" 是一个数据框,其中 spec1 和 spec2 的列名相同。我想从 "bounds" 中收集以下 5 列:
类型,cdf.mu.normal,cdf.above.mu.normal,cdf.mu.generic,cdf.above.mu.generic
每个规格放入一个数据帧。手动这很简单但很难看:
collectedManually <-list(
manual_spec1 = data.frame(
type=eba_results$spec1$bounds$type,
cdf.mu.normal=eba_results$spec1$bounds$cdf.mu.normal,
cdf.above.mu.normal=eba_results$spec1$bounds$cdf.above.mu.normal,
cdf.mu.generic=eba_results$spec1$bounds$cdf.mu.generic,
cdf.above.mu.generic=eba_results$spec1$bounds$cdf.above.mu.generic),
manual_spec2= data.frame(
type=eba_results$spec2$bounds$type,
cdf.mu.normal=eba_results$spec2$bounds$cdf.mu.normal,
cdf.above.mu.normal=eba_results$spec2$bounds$cdf.above.mu.normal,
cdf.mu.generic=eba_results$spec2$bounds$cdf.mu.generic,
cdf.above.mu.generic=eba_results$spec2$bounds$cdf.above.mu.generic))
但我有超过 2 个规范,我认为这应该可以通过 lapply 函数以更漂亮的方式实现。任何帮助将不胜感激!
p.s.: hrbrmstr 的答案适用但结果过于简单的通用示例:
exampleList = list(a=list(aa=data.frame(A=rnorm(10),B=rnorm(10)),bb=data.frame(A=rnorm(10),B=rnorm(10))),
b=list(aa=data.frame(A=rnorm(10),B=rnorm(10)),bb=data.frame(A=rnorm(10),B=rnorm(10))))
我想要一个对象,例如,将所有 A 和 B 向量收集到两个数据帧(每个数据帧都有其各自的 A 和 B),然后是数据帧列表.手动这看起来像:
dfa <- data.frame(A=exampleList$a$aa$A,B=exampleList$a$aa$B)
dfb <- data.frame(A=exampleList$a$aa$A,B=exampleList$a$aa$B)
collectedResults <- list(a=dfa, b=dfb)
可能有一种不太暴力的方法可以做到这一点。
如果您想要单个列的列表,这是一种方法:
get_col <- function(my_list, col_name) {
unlist(lapply(my_list, function(x) {
lapply(x, function(y) { y[, col_name] })
}), recursive=FALSE)
}
get_col(exampleList, "A")
get_col(exampleList, "B")
如果您想要合并 data.frame 指标列,这是一种方法:
collect_indicators <- function(my_list, indicators) {
lapply(my_list, function(x) {
do.call(rbind, c(lapply(x, function(y) { y[, indicators] }), make.row.names=FALSE))
})[[1]]
}
collect_indicators(exampleList, c("A", "B"))
如果您只是想将个人 data.frame 提高一个级别,以便更轻松地迭代以写入文件:
unlist(exampleList, recursive=FALSE)
关于真实输出格式的假设很多(问题有点含糊)。
有一种蛮力方法可行但依赖于几个命名对象:
collectEBA <- function(x){
df <- paste0("eba_results$",x,"$bounds")
df <- eval(parse(text=df))[,c("type",
"cdf.mu.normal","cdf.above.mu.normal",
"cdf.mu.generic","cdf.above.mu.generic")]
df[is.na(df)] <- "NA"
df
}
eba_export <- lapply(indicators,collectEBA)
names(eba_export) <- indicators
我正在使用 ExtremeBounds 包,它提供了一个多级列表,其中(除其他外)数据帧处于最低级别。我 运行 这个包超过了几个规范,我想在这些结果中收集一些选定数据框的列。这些应该按规范(下例中的 spec1 和 spec2)收集并排列在数据帧列表中。然后可以将此数据框列表用于各种用途,例如将不同规范的结果导出到不同的 Excel 表格中。
这是一些创建有问题对象的代码(只是 运行 盲目地使用这段代码,我的问题只涉及如何处理它创建的列表类型:eba_results ):
library("ExtremeBounds")
Data <- data.frame(var1=rbinom(30,1,0.2),var2=rbinom(30,2,0.2),
var3=rnorm(30),var4=rnorm(30),var5=rnorm(30))
spec1 <- list(y=c("var1"),
freevars=c("var2"),
doubtvars=c("var3","var4"))
spec2 <- list(y=c("var1"),
freevars=c("var2"),
doubtvars=c("var3","var4","var5"))
indicators <- c("spec1","spec2")
ebaFun <- function(x){
eba <- eba(data=Data, y=x$y,
free=x$freevars,
doubtful=x$doubtvars,
reg.fun=glm, k=1, vif=7, draws=50, weights = "lri", family = binomial(logit))}
eba_results <- lapply(mget(indicators),ebaFun) #eba_results is the object in question
手动我知道如何访问每个元素,例如:
eba_results$spec1$bounds$type #look at str(eba_results) to see the different levels
所以 "bounds" 是一个数据框,其中 spec1 和 spec2 的列名相同。我想从 "bounds" 中收集以下 5 列:
类型,cdf.mu.normal,cdf.above.mu.normal,cdf.mu.generic,cdf.above.mu.generic
每个规格放入一个数据帧。手动这很简单但很难看:
collectedManually <-list(
manual_spec1 = data.frame(
type=eba_results$spec1$bounds$type,
cdf.mu.normal=eba_results$spec1$bounds$cdf.mu.normal,
cdf.above.mu.normal=eba_results$spec1$bounds$cdf.above.mu.normal,
cdf.mu.generic=eba_results$spec1$bounds$cdf.mu.generic,
cdf.above.mu.generic=eba_results$spec1$bounds$cdf.above.mu.generic),
manual_spec2= data.frame(
type=eba_results$spec2$bounds$type,
cdf.mu.normal=eba_results$spec2$bounds$cdf.mu.normal,
cdf.above.mu.normal=eba_results$spec2$bounds$cdf.above.mu.normal,
cdf.mu.generic=eba_results$spec2$bounds$cdf.mu.generic,
cdf.above.mu.generic=eba_results$spec2$bounds$cdf.above.mu.generic))
但我有超过 2 个规范,我认为这应该可以通过 lapply 函数以更漂亮的方式实现。任何帮助将不胜感激!
p.s.: hrbrmstr 的答案适用但结果过于简单的通用示例:
exampleList = list(a=list(aa=data.frame(A=rnorm(10),B=rnorm(10)),bb=data.frame(A=rnorm(10),B=rnorm(10))),
b=list(aa=data.frame(A=rnorm(10),B=rnorm(10)),bb=data.frame(A=rnorm(10),B=rnorm(10))))
我想要一个对象,例如,将所有 A 和 B 向量收集到两个数据帧(每个数据帧都有其各自的 A 和 B),然后是数据帧列表.手动这看起来像:
dfa <- data.frame(A=exampleList$a$aa$A,B=exampleList$a$aa$B)
dfb <- data.frame(A=exampleList$a$aa$A,B=exampleList$a$aa$B)
collectedResults <- list(a=dfa, b=dfb)
可能有一种不太暴力的方法可以做到这一点。
如果您想要单个列的列表,这是一种方法:
get_col <- function(my_list, col_name) {
unlist(lapply(my_list, function(x) {
lapply(x, function(y) { y[, col_name] })
}), recursive=FALSE)
}
get_col(exampleList, "A")
get_col(exampleList, "B")
如果您想要合并 data.frame 指标列,这是一种方法:
collect_indicators <- function(my_list, indicators) {
lapply(my_list, function(x) {
do.call(rbind, c(lapply(x, function(y) { y[, indicators] }), make.row.names=FALSE))
})[[1]]
}
collect_indicators(exampleList, c("A", "B"))
如果您只是想将个人 data.frame 提高一个级别,以便更轻松地迭代以写入文件:
unlist(exampleList, recursive=FALSE)
关于真实输出格式的假设很多(问题有点含糊)。
有一种蛮力方法可行但依赖于几个命名对象:
collectEBA <- function(x){
df <- paste0("eba_results$",x,"$bounds")
df <- eval(parse(text=df))[,c("type",
"cdf.mu.normal","cdf.above.mu.normal",
"cdf.mu.generic","cdf.above.mu.generic")]
df[is.na(df)] <- "NA"
df
}
eba_export <- lapply(indicators,collectEBA)
names(eba_export) <- indicators