R 选择差值等于预定值的向量中的数对

R 选择差值等于预定值的向量中的数对,r,vector,R,Vector,我有一个数字向量,我想从中选择相隔2个单位的对。如果向量p定义如下: p<-c(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47) 我尝试在向量中至少选择这些数字,但没有成功 j<-NULL for(i in seq(p)) if (p[i+1]-p[i]==2) j<-c(j,i,i+1) jHi如果期望的结果是数据帧,则尝试此操作 p<-c(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47) a&l

我有一个数字向量,我想从中选择相隔2个单位的对。如果向量
p
定义如下:

p<-c(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47)
我尝试在向量中至少选择这些数字,但没有成功

j<-NULL
for(i in seq(p)) if (p[i+1]-p[i]==2) j<-c(j,i,i+1)

jHi如果期望的结果是数据帧,则尝试此操作

p<-c(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47)

a<-which(p-lag(p)==2)
b<-a-1

df<-data.frame(pair1=p[b],
               pair2=p[a])

pHi如果所需结果是数据帧,则尝试此操作

p<-c(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47)

a<-which(p-lag(p)==2)
b<-a-1

df<-data.frame(pair1=p[b],
               pair2=p[a])

p有比这更好的方法,但是这里有一个关于
expand.grid
的想法

df <- expand.grid(p, p)
unname(apply(df[df[,1]-df[,2] == -2,], 1,paste, collapse = ','))
#[1] "3,5"   "5,7"   "11,13" "17,19" "29,31" "41,43"

有一种比这更好的方法,但这里有一个关于
expand.grid
的想法

df <- expand.grid(p, p)
unname(apply(df[df[,1]-df[,2] == -2,], 1,paste, collapse = ','))
#[1] "3,5"   "5,7"   "11,13" "17,19" "29,31" "41,43"

您可以使用
dplyr
执行此操作,它将在数据帧中返回对:

> library(dplyr)
> data.frame(p) %>% mutate(lagp = lag(p))  %>% filter(p - lagp == 2)
   p lagp
1  5    3
2  7    5
3 13   11
4 19   17
5 31   29
6 43   41

您可以使用
dplyr
执行此操作,它将在数据帧中返回对:

> library(dplyr)
> data.frame(p) %>% mutate(lagp = lag(p))  %>% filter(p - lagp == 2)
   p lagp
1  5    3
2  7    5
3 13   11
4 19   17
5 31   29
6 43   41

以下是我使用基本R函数的解决方案:

dif=which(abs(diff(p))==2)
sapply(dif, function(x) c(p[x],p[x+1]))

   # [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    3    5   11   17   29   41
# [2,]    5    7   13   19   31   43
通过将
2
更改为任何其他值,可以获得向量元素与之分离的任何所需单位的结果

abs
用于处理向量元素未排序的情况

基准(小规模)


以下是我使用基本R函数的解决方案:

dif=which(abs(diff(p))==2)
sapply(dif, function(x) c(p[x],p[x+1]))

   # [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    3    5   11   17   29   41
# [2,]    5    7   13   19   31   43
通过将
2
更改为任何其他值,可以获得向量元素与之分离的任何所需单位的结果

abs
用于处理向量元素未排序的情况

基准(小规模)


下面是另一个使用
数据的表

library(data.table) 
setDT(list(p=p))[, p1 := shift(p)][p-p1 ==2]
#    p p1
#1:  5  3
#2:  7  5
#3: 13 11
#4: 19 17
#5: 31 29
#6: 43 41
如果未对
向量
p进行排序,
在执行操作之前对其进行排序

setDT(list(p=p))[order(p)][, p1 := shift(p)][p-p1==2]
使现代化 使用@RHertel提供的新向量

p <- c(2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47)
unique(CJ(p=p, p1=p)[abs(p-p1)==2][.(p=pmin(p,p1), p1=pmax(p, p1))])
#    p p1
#1:  2  4
#2:  3  5
#3:  5  7
#4: 11 13
#5: 17 19
#6: 29 31
#7: 41 43

p这里是另一个使用
数据的表

library(data.table) 
setDT(list(p=p))[, p1 := shift(p)][p-p1 ==2]
#    p p1
#1:  5  3
#2:  7  5
#3: 13 11
#4: 19 17
#5: 31 29
#6: 43 41
如果未对
向量
p进行排序,
在执行操作之前对其进行排序

setDT(list(p=p))[order(p)][, p1 := shift(p)][p-p1==2]
使现代化 使用@RHertel提供的新向量

p <- c(2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47)
unique(CJ(p=p, p1=p)[abs(p-p1)==2][.(p=pmin(p,p1), p1=pmax(p, p1))])
#    p p1
#1:  2  4
#2:  3  5
#3:  5  7
#4: 11 13
#5: 17 19
#6: 29 31
#7: 41 43

p有点老套,但这里有另一种方法

d2_mat <- which(as.matrix(dist(p))==2, arr.ind=TRUE)
unique(t(apply(cbind(p[d2_mat[,1]],p[d2_mat[,2]]),1,sort)))
#     [,1] [,2]
#[1,]    3    5
#[2,]    5    7
#[3,]   11   13
#[4,]   17   19
#[5,]   29   31
#[6,]   41   43
在最后一行中,您也可以使用
paste()
,而不是
cbind()
,具体取决于所需的输出:

paste(p[idx[,1]], p[idx[,2]], sep=",")
#[1] "3,5"   "5,7"   "11,13" "17,19" "29,31" "41,43"

下面的变体比我以前的建议更简单,可能(快得多)

m2 <- t(combn(sort(p),2))
m2[abs(m2[,1] - m2[,2]) == 2,]

m2有点老套,但这里有另一种方法

d2_mat <- which(as.matrix(dist(p))==2, arr.ind=TRUE)
unique(t(apply(cbind(p[d2_mat[,1]],p[d2_mat[,2]]),1,sort)))
#     [,1] [,2]
#[1,]    3    5
#[2,]    5    7
#[3,]   11   13
#[4,]   17   19
#[5,]   29   31
#[6,]   41   43
在最后一行中,您也可以使用
paste()
,而不是
cbind()
,具体取决于所需的输出:

paste(p[idx[,1]], p[idx[,2]], sep=",")
#[1] "3,5"   "5,7"   "11,13" "17,19" "29,31" "41,43"

下面的变体比我以前的建议更简单,可能(快得多)

m2 <- t(combn(sort(p),2))
m2[abs(m2[,1] - m2[,2]) == 2,]
m2
使用长度函数而不是seq来获得所需的输出
j
使用长度函数而不是seq来获得所需的输出


jIt对我不起作用,因为df是空的。我检查了p-lag(p),它给出了一个向量0sPerhaps,当res为NULL时,我做错了什么。你试过你的解决办法吗?我复制了你们的答案,但它不起作用。我试过了,它起作用了。基本上,问题是,当你们做p-lag(p)时,你们得到了0。这将使p的第一个元素和第二个元素产生差异,然后使p的第二个元素和第三个元素产生差异。但对你来说,它不起作用。我不明白最初的问题是什么。现在p-lag(p)给出了正确的输出。谢谢。只需使用
diff
而不是
lag
。它对我也不起作用(获取一个空的data.frame)。它对我不起作用,因为df是空的。我检查了p-lag(p),它给出了一个向量0sPerhaps,当res为NULL时,我做错了什么。你试过你的解决办法吗?我复制了你们的答案,但它不起作用。我试过了,它起作用了。基本上,问题是,当你们做p-lag(p)时,你们得到了0。这将使p的第一个元素和第二个元素产生差异,然后使p的第二个元素和第三个元素产生差异。但对你来说,它不起作用。我不明白最初的问题是什么。现在p-lag(p)给出了正确的输出。谢谢。只需使用
diff
而不是
lag
。它也不适合我(得到一个空的data.frame)。谢谢。你知道为什么我的代码没有正确选择数字吗?你的代码的问题是你使用的是索引
i
,而不是
p[i]
。如果(p[i+1]-p[i]==2,则尝试
for(i在序列(p)中)j@David_B谢谢你的建议。然而,它给了我一个错误“缺少值,需要TRUE/FALSE”,尽管如此,向量包含所需的值。谢谢。错误是因为您要求R在1到15之间的序列上循环,15是
p
的长度,但是
if
语句包含了对
p[i+1]
的引用,在循环的最后一次迭代中将是
p[16]
,这是不存在的。但是到那时,循环已经完成了你想要的工作。如果您想防止错误,只需将循环更改为
for(i in 1:14)
。谢谢。你知道为什么我的代码没有正确选择数字吗?你的代码的问题是你使用的是索引
i
,而不是
p[i]
。如果(p[i+1]-p[i]==2,则尝试
for(i在序列(p)中)j@David_B谢谢你的建议。然而,它给了我一个错误“缺少值,需要TRUE/FALSE”,尽管如此,向量包含所需的值。谢谢。错误是因为您要求R在1到15之间的序列上循环,15是
p
的长度,但是
if
语句包含了对
p[i+1]
的引用,在循环的最后一次迭代中将是
p[16]
,这是不存在的。但是到那时,循环已经完成了你想要的工作。如果您想防止错误,只需将循环更改为
for(i in 1:14)
。这比我首先批准的答案更方便。谢谢。这个解决方案也假设
p
中的值是有序的。这比我首先批准的答案更方便。谢谢。这个解决方案也假设
p