r-将用户编写的函数迭代应用于存储在两个不同数据帧列中的对



考虑以下数据:

set.seed(123)
dat1 <- data.frame(Loc = rep(letters[1:20], each = 10),
ID = 1:200,
var1 = rnorm(200),
var2 = rnorm(200),
var3 = rnorm(200),
var4 = rnorm(200),
var5 = rnorm(200),
var6 = rnorm(200))
dat1$ID <- factor(dat1$ID)

从20个不同的群体中随机抽取个体(每个个体具有唯一的ID(,这些群体由分组变量Loc表示。对每个ID进行6个不同变量(每个var.(的测量。我正在使用vegan软件包来执行anosim()。我想在dat1中的每对可能的Loc之间进行成对比较。我写这个函数是为了进行成对比较:

library(vegan)
anosim.res <- data.frame()
pwc.anosim <- function(g1, g2){#g1 and g2 are the groups
dat <- dplyr::filter(dat1, Loc == g1 | Loc == g2)
vars <- dat[,3:8]#get the variables
vars <- scale(vars)#scale them
dmat <- vegdist(vars, method = "euclidian")#calculate a distance matrix 
res <- anosim(dmat, dat$Loc)#perform the anosim between the two Locs
out <- data.frame(Group1 = g1,
Group2 = g2,
R = res$statistic,
p = res$signif)#make a column for each of the groups, and get the stats
anosim.res <<- rbind(anosim.res,out)#store out in the external data frame 
} 
#this will be to store the results:
anosim.res<-data.frame()
#try it with 2 random Locs a and b: 
pwc.anosim(g1 = "a", g2 = "b")

当我单独指定Loc时,这很好。现在我想循环遍历Locs的所有可能组合,所以我将对象Pairs:

Pairs <-expand.grid(unique(dat1$Loc),unique(dat1$Loc))

我想我可以循环遍历Loc中存储的每对组,如下所示:

for(i in Pairs[,1]){
for(j in Pairs[,2]){
pwc.anosim(g1=i, g2=j)
}
}
#or:
for(i in Pairs$Var1){
for(j in Pairs$Var2){
pwc.anosim(g1=i, g2=j)
}
}

但我得到以下错误:

Error in data.frame(Group1 = g1, Group2 = g2, R = res$statistic, p = res$signif) : arguments imply differing number of rows: 1, 0

我做错了什么?如何在每对Loc上使用此函数?

由于您已经通过调用expand.grid枚举了对的每个组合,因此不需要嵌套循环-您只需要在Pairs:上执行一个循环

for (i in 1:nrow(Pairs)) {
pwc.anosim2(g1=Pairs[i, 1], g2=Pairs[i, 2])
}

或者,更简洁地说,

purrr::walk2(Pairs[[1]], Pairs[[2]], pwc.anosim2)

确保pwc.anosim2可以处理因子输入,因为expand.grid默认情况下会生成因子的数据帧,包括在R 4.0.0+中。

最新更新