这是我的问题:我有两个不同的数据框(A和B).每个数据框的列是地理位置,行数据是地点的种类.我需要将数据名称A的地点1的物种列表与数据帧B的所有地点的物种列表相交.为此我写了一个这样的循环:
res<-list()
for(i in 1:length(B)) {intersect(A[1], B[i])->res[[i]]
}
Run Code Online (Sandbox Code Playgroud)
现在我必须为A的地点2,3,4,5,6 .....重复相同的循环,也就是说我必须将A的所有地点与B的所有地点相交.
谢谢.
这是一种类似于使用嵌套循环的方法lapply().
如果您有一个大型数据集,使用lapply()可能会比使用循环获得非常可观的速度提升.循环是R中慢,建议在使用矢量化功能的*apply家庭在可能的情况.
我将通过一个示例,您可以将其调整为您的数据集.
首先,我们创建一个名为样本3x3的数据帧df,以列a,b并c和行d,e以及f:
> df <- data.frame(a = sample(3), b = sample(3), c = sample(3))
> rownames(df) <- c('d','e','f')
Run Code Online (Sandbox Code Playgroud)
让我们来看看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
Run Code Online (Sandbox Code Playgroud)
比方说,我们要intersect的列向量df和t(df).我们现在使用嵌套lapply()语句来运行intersect()来自两者的列向量df和转置t(df):
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))
Run Code Online (Sandbox Code Playgroud)
结果是a 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
Run Code Online (Sandbox Code Playgroud)
让我们来看看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
Run Code Online (Sandbox Code Playgroud)
让我们看看df$a与之相交t(df)$d,t(df)$e并且t(df)$f:
$a
$a$d
[1] 3 1
Run Code Online (Sandbox Code Playgroud)
相交矢量a和d:{3,1,2}^{3,1,3} = {3,1}
$a$e
[1] 3 1
Run Code Online (Sandbox Code Playgroud)
再次,使用向量a和e:{3,1,2}^{1,3,1} = {3,1}
$a$f
[1] 2
Run Code Online (Sandbox Code Playgroud)
最后,使用向量a和f:{3,1,2}^{2,2,2} = {2}
其他项目result如下.
要将其扩展到数据集,请将您的数据框列视为地点,将transposed-data-frame列视为您的物种.然后使用lapply(),如上所示.
要分解嵌套lapply()语句,请从内部开始lapply():
lapply(as.data.frame(t(df)), function(y) ... )
Run Code Online (Sandbox Code Playgroud)
这意味着每个列向量t(df)- 列$ d,$ e和$ f - 由变量yin 表示function(y).我们将...在一秒钟后回来.
现在让我们来看看外面lapply():
lapply(df, function(x) ... )
Run Code Online (Sandbox Code Playgroud)
这意味着df- 列$ a,$ b和$ c 中的每个列向量都由变量xin 表示function(x).
现在让我们解释一下....
外...是任何功能的x-这可以是length(),sum()等,甚至是另一个lapply().内lapply()有自己的函数和变量名y,所以内...可以运行在两种功能:x和y.
这就是我们所做的:对于每个列向量df,我们在df-vector和transpose中的每个列向量上运行一个函数t(df).在我们的例子中,函数我们就会对x和y是intersect():
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))
Run Code Online (Sandbox Code Playgroud)