生成多个数据集并应用函数,输出多个数据集。

4

我有一个问题,对我来说很难...

我希望生成多个数据集,并对这些数据集应用函数,输出相应的单个或多个数据集的输出(尽可能)...

我的例子,虽然我需要生成大量的变量和数据集。

seed <- round(runif(10)*1000000)

datagen <- function(x){
set.seed(x)
var <- rep(1:3, c(rep(3, 3)))
yvar <- rnorm(length(var), 50, 10)
matrix <- matrix(sample(1:10, c(10*length(var)), replace = TRUE), ncol = 10)
mydata <- data.frame(var, yvar, matrix)
}

gdt <- lapply (seed,  datagen) 

# resulting list (I believe is correct term) has 10 dataframes: 
# gdt[1] .......to gdt[10]

# my function, this will perform anova in every component data frames and 
#output probability coefficients...  
anovp <- function(x){
          ind <- 3:ncol(x) 
          out <- lm(gdt[x]$yvar ~ gdt[x][, ind[ind]])
          pval <- out$coefficients[,4][2]
          pval <- do.call(rbind,pval) 
         }

plist <- lapply (gdt,  anovp) 

Error in gdt[x] : invalid subscript type 'list'

这个无法正常工作,我尝试了不同的选项。但是没能找出解决方法...最终决定请教专家,非常抱歉...

我的问题如下:

(1) 是否可以以这种方式处理这样的情况,或者有其他方法可以处理创建的多个数据集?

(2) 如果这是正确的方式,我该如何操作?

感谢您的关注和帮助...

1个回答

7
您的基本想法是正确的,您应该创建一个数据框列表,然后使用lapply将函数应用于列表的每个元素。不幸的是,您的代码中有几个奇怪之处。
随机生成种子并设置它是没有意义的。您只需要使用set.seed使随机数可重现即可。删除这些行。
seed <- round(runif(10)*1000000)

或许

set.seed(x)

rep(1:3, c(rep(3, 3)))rep(1:3, each = 3)相同。


不要把你的变量命名为varmatrix,因为它们会掩盖那些函数的名称,这很容易引起混淆。


3:ncol(x)是有风险的。如果x的列数小于3,它将不会执行您期望的操作。


...现在,您实际想解决的问题。

问题出在out <- lm(gdt[x]$yvar ~ gdt[x][, ind[ind]])这一行。

lapply将数据框传递到anovp中,而不是索引,所以xgdt[x]中是一个数据框,这会导致错误。


还有一件事。当您重写那行代码时,请注意lm接受一个数据参数,因此您不需要像gdt$some_column那样做;您可以直接引用some_column


编辑:进一步建议。

您似乎总是使用公式yvar ~ X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10。由于每次都相同,因此在调用lapply之前创建它。


independent_vars <- paste(colnames(gdt[[1]])[-1:-2], collapse = " + ")
model_formula <- formula(paste("yvar", independent_vars, sep = " ~ "))

我觉得你不需要使用anovp函数,只需要执行以下操作:

models <- lapply(gdt, function(data) lm(model_formula, data))

如果需要,可以包含一个进一步的对lapply的调用来修改系数。下一行复制了你的anovp代码,但不会起作用,因为model$coefficients是一个向量(因此维度不正确)。调整代码以检索实际需要的部分。

coeffs <- lapply(models, function(model) do.call(rbind, model$coefficients[,4][2]))

除了不使用函数名称的理由外,这是一条好建议。对象名称保留在单独的列表中。创建一个名为"var"的对象不会屏蔽var函数,但这仍然不是一个好主意,因为人类大脑并不像计算机那样有条理。 - IRTFM
@DWin:确实,R在判断变量或函数时还算合理,但有些模糊的情况下会出现掩盖效应。例如,在命令提示符处键入“var”,R会打印出函数定义。现在定义“var <- 1:5”,再重复上述操作,这次变量就会被打印出来。 - Richie Cotton
@RichieCotton 不错的回答,但我同意 @DWin 的掩码观点 - 这不是一个问题。请参阅 https://dev59.com/cG025IYBdhLWcg3wOzTX 以获取解释。代码 x <- 1:5; var(x); var <- "a"; var; var(x) 将按您的预期执行所有操作,尽管有一个名为 var 的新变量。 - Andrie
非常感谢您...我尝试了以下方法-仍然没有成功...我还是没有理解您的意思..."anovp <- function(x){ ind <- 3:ncol(x) out <- lm(x[,3] ~ x[, ind]) pval <- out$coefficients[,4][2] pval <- do.call(rbind,pval) } - jon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接