这是使用lapply() 的嵌套循环的类似方法。
如果您有一个大型数据集,与使用循环相比,使用 lapply() 可能会大大提高您的速度。 R中循环比较慢,建议尽可能使用the *apply family中的向量化函数。
我将通过一个示例进行演示,您也许可以将其调整为您的数据集。
首先,我们创建一个名为 df 的示例 3x3 数据框,列有 a、b 和 c,行有 d、e 和 f:
> df <- data.frame(a = sample(3), b = sample(3), c = sample(3))
> rownames(df) <- c('d','e','f')
让我们看看df及其转置t(df):
> df
a b c
d 3 1 3
e 1 3 1
f 2 2 2
> t(df)
d e f
a 3 1 2
b 1 3 2
c 3 1 2
假设我们想要intersect df 和 t(df) 的列向量。我们现在使用嵌套的lapply() 语句在来自df 和转置t(df) 的列向量上运行intersect():
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))
结果是list(),显示交集结果:
> is.list(result)
[1] TRUE
> print(result)
$a
$a$d
[1] 3 1
$a$e
[1] 3 1
$a$f
[1] 2
$b
$b$d
[1] 1 3
$b$e
[1] 1 3
$b$f
[1] 2
$c
$c$d
[1] 3 1
$c$e
[1] 3 1
$c$f
[1] 2
让我们再看看df和t(df),看看如何读取这些结果:
> df
a b c
d 3 1 3
e 1 3 1
f 2 2 2
> t(df)
d e f
a 3 1 2
b 1 3 2
c 3 1 2
让我们看看df$a与t(df)$d、t(df)$e和t(df)$f相交:
$a
$a$d
[1] 3 1
与向量a 和d 相交:{3,1,2}^{3,1,3} = {3,1}
$a$e
[1] 3 1
同样,使用向量 a 和 e:{3,1,2}^{1,3,1} = {3,1}
$a$f
[1] 2
最后,使用向量 a 和 f:{3,1,2}^{2,2,2} = {2}
result 中的其他项目如下。
要将其扩展到您的数据集,请将您的数据框列视为localities,将转置数据框列视为您的物种。然后使用lapply(),如上图。
要分解嵌套的lapply() 语句,请从内部lapply() 开始:
lapply(as.data.frame(t(df)), function(y) ... )
这意味着t(df) 中的每个列向量——$d、$e 和$f 列——都由function(y) 中的变量y 表示。我们稍后会回到...。
现在我们看看外层lapply():
lapply(df, function(x) ... )
这意味着df 中的每个列向量($a、$b 和 $c 列)都由 function(x) 中的变量 x 表示。
现在让我们解释一下...。
外部... 是x 的任何函数——这可以是length()、sum() 等,甚至是另一个lapply()。内部lapply() 有自己的函数和变量名y,因此内部... 可以在x 和y 上运行函数。
这就是我们所做的:对于df 中的每个列向量,我们对该df-vector 和转置t(df) 中的每个列向量运行一个函数。在我们的示例中,我们将在x 和y 上运行的函数是intersect():
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))