R 如何识别两个向量中的多个相同对
在我的图形包(在图论中,节点通过边连接)中,我有一个向量,用于指示每条边的原点节点R 如何识别两个向量中的多个相同对,r,R,在我的图形包(在图论中,节点通过边连接)中,我有一个向量,用于指示每条边的原点节点从,一个向量,用于指示每条边的目标节点到,以及一个向量,用于指示每条边的曲线曲线 默认情况下,如果两个节点之间只有一条边,则希望边的曲线为0;如果两个节点之间有两条边,则希望边的曲线为0.2。我现在使用的代码是for循环,速度有点慢: curve <- rep(0,5) from<-c(1,2,3,3,2) to<-c(2,3,4,2,1) for (i in 1:length(from
从
,一个向量,用于指示每条边的目标节点到
,以及一个向量,用于指示每条边的曲线曲线
默认情况下,如果两个节点之间只有一条边,则希望边的曲线为0;如果两个节点之间有两条边,则希望边的曲线为0.2。我现在使用的代码是for循环,速度有点慢:
curve <- rep(0,5)
from<-c(1,2,3,3,2)
to<-c(2,3,4,2,1)
for (i in 1:length(from))
{
if (any(from==to[i] & to==from[i]))
{
curve[i]=0.2
}
}
在这两个向量中,对3与对10相同(1和7的顺序不同),对4和12相同(2和8)。所以我希望curve
成为:
[1,] 0.0
[2,] 0.0
[3,] 0.2
[4,] 0.2
[5,] 0.0
[6,] 0.0
[7,] 0.0
[8,] 0.0
[9,] 0.0
[10,] 0.2
[11,] 0.0
[12,] 0.2
[13,] 0.0
[14,] 0.0
[15,] 0.0
[16,] 0.0
[17,] 0.0
(作为向量,我转置了两次以获得行号)
解决方案
from to,from,to))
+配音#Maiasaura:
>图书馆(plyr)
>
>系统时间(
+ {
+data=data.frame(cbind(id=1:length(from)、from、to))
+数据=ddply(数据,.(id),变换,f1=min(从,到),f2=max(从,到))
+曲线=数据。帧(数据[其中(重复的(数据[,4:5])==真),],值=0.2)
+结果=连接(数据[,4:5],曲线[,4:6],通过=相交(名称(数据)[4:5],名称(曲线)[4:6]))
+结果$value[即.na(结果$value))]=0
+结果=数据帧(从,到,曲线=结果$value)
+ })
用户系统运行时间
103.43 0.11 103.95
>#马雷克1+约书亚
>>系统时间(
> + {
>+srt+曲线1,
> 0.2, 0)
>+})用户系统已运行
> 7.26 0.00 7.25
最快的解决方案是:
srt <- cbind(pmin(from,to), pmax(from,to) )
dub <- duplicated(srt)|duplicated(srt,fromLast=T)
curve <- ifelse(dub,0.2,0)
srt使用outer
怎么样
from <- c(1,2,3,3,2)
to <- c(2,3,4,2,1)
out <- outer(from, to, `==`)
ifelse(rowSums(out) > 0 & colSums(out) > 0, 0.2, 0)
from使用outer
怎么样
from <- c(1,2,3,3,2)
to <- c(2,3,4,2,1)
out <- outer(from, to, `==`)
ifelse(rowSums(out) > 0 & colSums(out) > 0, 0.2, 0)
从更改
any(from==to[i] & to==from[i])
到
可以节省不少时间。在您的示例中,如果将from
和to
复制5000次,计算时间将减少1/3
使用&&
时,如果第一个条件为FALSE
R,则不必计算第二个表达式 变化
any(from==to[i] & to==from[i])
到
可以节省不少时间。在您的示例中,如果将from
和to
复制5000次,计算时间将减少1/3
使用&&
时,如果第一个条件为FALSE
R,则不必计算第二个表达式 如果我理解正确,您可以在%
中使用%:
curve[ to %in% from & from %in% to ] <- 0.2
曲线[to%in%from&from%in%to]如果我理解正确,您可以使用%in%
:
curve[ to %in% from & from %in% to ] <- 0.2
curve[从%in%到%in%和从%in%到]这里有一个使用plyr的解决方案
我首先将from
和to
组合成一个数据框
library(plyr)
data=data.frame(cbind(id=1:length(from),from,to))
资料
然后,以下内容应产生您寻求的结果:
data=ddply(data, .(id), transform, f1=min(from,to),f2=max(from,to))
curved=data.frame(data[which(duplicated(data[,4:5])==TRUE),],value=0.2)
result=join(data[,4:5],curved[,4:6],by=intersect(names(data)[4:5],names(curved)[4:6]))
result$value[which(is.na(result$value))]=0
result=data.frame(from,to,curve=result$value)
应产生:
from to curve
1 4 1 0.0
2 6 1 0.0
3 7 1 0.2
4 8 2 0.2
5 1 3 0.0
6 9 3 0.0
7 5 4 0.0
8 1 5 0.0
9 2 6 0.0
10 1 7 0.2
11 10 7 0.0
12 2 8 0.2
13 6 8 0.0
14 7 8 0.0
15 10 8 0.0
16 4 10 0.0
17 9 10 0.0
您可以将上述代码转换为函数
calculate_curve <- function (from,to)
{
data=data.frame(cbind(id=1:length(from),from,to))
data=ddply(data, .(id), transform, f1=min(from,to),f2=max(from,to))
curved=data.frame(data[which(duplicated(data[,4:5])==TRUE),],value=0.2)
result=join(data[,4:5],curved[,4:6],by=intersect(names(data)[4:5],names(curved)[4:6]))
result$value[which(is.na(result$value))]=0
return (result$value)
}
下面是一个使用plyr
我首先将from
和to
组合成一个数据框
library(plyr)
data=data.frame(cbind(id=1:length(from),from,to))
资料
然后,以下内容应产生您寻求的结果:
data=ddply(data, .(id), transform, f1=min(from,to),f2=max(from,to))
curved=data.frame(data[which(duplicated(data[,4:5])==TRUE),],value=0.2)
result=join(data[,4:5],curved[,4:6],by=intersect(names(data)[4:5],names(curved)[4:6]))
result$value[which(is.na(result$value))]=0
result=data.frame(from,to,curve=result$value)
应产生:
from to curve
1 4 1 0.0
2 6 1 0.0
3 7 1 0.2
4 8 2 0.2
5 1 3 0.0
6 9 3 0.0
7 5 4 0.0
8 1 5 0.0
9 2 6 0.0
10 1 7 0.2
11 10 7 0.0
12 2 8 0.2
13 6 8 0.0
14 7 8 0.0
15 10 8 0.0
16 4 10 0.0
17 9 10 0.0
您可以将上述代码转换为函数
calculate_curve <- function (from,to)
{
data=data.frame(cbind(id=1:length(from),from,to))
data=ddply(data, .(id), transform, f1=min(from,to),f2=max(from,to))
curved=data.frame(data[which(duplicated(data[,4:5])==TRUE),],value=0.2)
result=join(data[,4:5],curved[,4:6],by=intersect(names(data)[4:5],names(curved)[4:6]))
result$value[which(is.na(result$value))]=0
return (result$value)
}
谢谢唯一的问题是它分配了一个矩阵。如果我使用100k的边来实现这一点,我的循环可以工作(5分钟左右),但是1e+10元素矩阵太大,无法存储(内存不足,即使使用我的12G RAM),谢谢。唯一的问题是它分配了一个矩阵。如果我用100k的边这样做,我的循环可以工作(5分钟左右),但是1e+10元素矩阵太大,无法存储(内存不足,即使是我的12G RAM),谢谢,但这不是我的意思。我已经编辑了这篇文章,希望它能更清晰一点。@Sacha:我已经用另一个选项更新了我的答案。如果您只使用t
一次(在创建srt
时),而不是在每次重复的调用中使用一次,您的解决方案会更快一些。谢谢,但这不是我的意思。我已经编辑了这篇文章,希望它能更清晰一点。@Sacha:我已经用另一个选项更新了我的答案。如果您只使用t
一次(在创建srt
时),而不是在每个重复的调用中使用一次,那么您的解决方案会快一点。谢谢,但这只说明索引值到[i]
发生在from
中的某个位置,而索引值from[i]
发生在到中。几乎总是这样,我感兴趣的是,如果这对c(从[I]到[I])
在另一个时间发生,可能是以尊敬的顺序发生。谢谢,但这只说明索引值到[I]
发生在从到的某个地方,而索引值从[I]
发生在到中。几乎总是这样,如果这对c(从[I]到[I])
在另一时间出现,我感兴趣的是,可能是以尊敬的顺序出现。太棒了,谢谢。duplicated
功能就是我需要的功能。我做了一个更为节俭的版本(见问题),但我会接受这个版本,谢谢。duplicated
功能就是我需要的功能。我做了一个更简洁的版本(见问题),但我接受这个,因为这个apply
部分非常慢,请尝试cbind(pmin(from,to),pmax(from,to))
(它已经被转移了)。或者cbind(ifelse(from>to,to,from),ifelse(from>to,from,to))
这个apply
部分非常慢,请尝试cbind(pmin(from,to),pmax(from,to))
。或者cbind(ifelse(from>to,to,from),ifelse(from>to,from,to))
。