2012-01-11 146 views
2

这是我的问题:我有两个不同的数据帧(A和B)。每个数据框的列是一个地理位置,行数据是一个地区的物种。我需要相交的数据帧B的所有地区的物种列表中的数据成名的地方1个品种的名单要做到这一点,我写了这样一个循环:R中循环的循环

res<-list() 
for(i in 1:length(B)) {intersect(A[1], B[i])->res[[i]] 
} 

现在我必须重复A的局部2,3,4,5,6,......的相同循环,也就是说我必须与B的所有地点A相交所有地点。

谢谢。

+0

欢迎SO。如果您提供样本数据,问题更容易回答。 – 2012-01-11 10:48:58

回答

3

很难完全理解你想要得到的结果。但是,如果我正确地猜出了你的需求,下面的代码将会做你想做的事。这个代码当然可以进一步优化以提高速度,因为对于大数据集,它可能不会太快。

res <- list() 
for (i in 1:ncol(A)) { 
    res[[i]] <- list() 
    for (j in 1:ncol(B)) { 
    res[[i]][[j]] <- intersect(A[,i], B[,j]) 
    } 
} 

要访问的结果,您可以使用

res[[column_index_in_A]][[column_index_in_B]] 
+0

是的,是的是的!!!!!非常感谢DrDom!有用! – user1142777 2012-01-11 11:51:29

1

这里胡乱猜测你的数据:

A <- data.frame(
    London  = c(TRUE, TRUE, FALSE), 
    Manchester = c(FALSE, TRUE, FALSE), 
    Birmingham = c(TRUE, FALSE, TRUE), 
    row.names = c("rats", "mice", "foxes") 
) 

B <- data.frame(
    London  = c(TRUE, FALSE, FALSE), 
    Manchester = c(TRUE, TRUE, TRUE), 
    Birmingham = c(TRUE, TRUE, FALSE), 
    row.names = c("rats", "mice", "foxes")  
) 


> A 
     London Manchester Birmingham 
rats TRUE  FALSE  TRUE 
mice TRUE  TRUE  FALSE 
foxes FALSE  FALSE  TRUE 
> B 
     London Manchester Birmingham 
rats TRUE  TRUE  TRUE 
mice FALSE  TRUE  TRUE 
foxes FALSE  TRUE  FALSE 

在这种情况下,找到存在于同一位置的两个物种数据集,您只需要

as.matrix(A) & as.matrix(B) 
+0

谢谢,但我需要将注意力集中在动物群列表的交集处,因为我需要计算相似索引 – user1142777 2012-01-11 13:08:56

5

下面是使用lapply()的嵌套循环的类似方法。

如果你有一个大的数据集,使用lapply()可能会使你在使用循环方面获得相当可观的速度提升。循环中R的速度较慢,建议在可能的情况下使用矢量化函数the *apply family

我将介绍一个例子,并且可以将其应用于您的数据集。

首先,我们创建一个名为df样品3x3的数据帧,与ba,并且c,和行def

> 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列vect dft(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)$dt(df)$et(df)$f

$a 
$a$d 
[1] 3 1 

相交的矢量ad{3,1,2}^{3,1,3} = {3,1}

$a$e 
[1] 3 1 

再次,载体ae{3,1,2}^{1,3,1} = {3,1}

$a$f 
[1] 2 

最后,用载体af{3,1,2}^{2,2,2} = {2}

result后续其他项目。

将其扩展到数据集,觉得你的数据帧列作为地方和换位数据帧列,您。然后使用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,所以内部...可以在xy上运行功能。

所以,这就是我们做的:对于每df列向量,我们运行对df维矢量,并在转t(df)每列向量函数。在我们的例子中,函数我们就会对xyintersect()

> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y))) 
+0

这是一个非常有趣的过程。这是我尝试的第一种方式,但只有现在我才能理解lapply的工作原理。这个解释非常有用。谢谢 – user1142777 2012-01-11 13:16:09