我尝试了一些purrr
成语 - 特别是循环(或者如果你愿意应用)的函数通过一个data.frame运行并与另一个data.frame中的所有其他行进行比较......并根据该比较函数过滤笛卡尔积。
> df1
chr start end
(fctr) (int) (int)
1 chr1 9069 9176
2 chr1 10460 11368
3 chr1 34633 35625
4 chr1 36791 37023
> df2
chr start2
(fctr) (dbl)
1 chr1 9169
2 chr1 10360
3 chr1 34633
所以一个简单的示例函数是:
> is.between <- function(x1, y1, y2){
ifelse(x1 >= y1 & x1 <= y2, TRUE, FALSE)
}
我正在寻找的结果(现在)应该是2乘4的数据。df3
喜欢
# desired result
chr start end start2
(fctr) (int) (int)
1 chr1 9069 9176 9169
2 chr1 34633 35625 34633
天真然后我尝试使用purrr::cross_n
函数,就像这样......
> cross_n(list(df2$start2, df1$start, df1$start), .filter = is.between)
当然,它不起作用,它正在搜索3个输入列(48种组合)的笛卡尔积。我希望搜索df2$start2
与[df1$start
和df1$end
](12种组合)的组合。
所以......有没有办法在purrr
框架内做到这一点?
无法使用cross_n
或cross2
并且错误地了解它...我不完全理解cross_d
上的文档
答案 0 :(得分:1)
好的FWIW - 我已经调整了一些purrr::cross_n
函数来回答我自己的问题。新函数cross2d
如下所示:
# this makes sense only if the .l in the same groups are the same length
# ie they are probably from the same data.frame
cross2d<- function(.l, groups = NULL, .filter = NULL){
if (is_empty(.l) | is.null(groups)) {
return(.l)
}
if (!is.null(.filter)) {
.filter <- as_function(.filter)
}
n <- length(.l)
#separate df for each group
df1<- data.frame(.l[groups==0])
df2<- data.frame(.l[groups==1])
exp.coords<-expand.grid(1:nrow(df1), 1:nrow(df2))
df<- data.frame(df1[exp.coords$Var1,], df2[exp.coords$Var2,])
names(df)<-c(colnames(df1),colnames(df2))
df[do.call(.filter, unname(df)),]
}
使用上面显示的示例数据df1
和df2
以及is.between
函数,您可以像这样使用它:
> cross2d(list(x1=df2$start, x2=df1$start, y2=df1$end), group=c(0,1,1), .filter=is.between)
x1 x2 y2
1 9169 9069 9176
3.2 34633 34633 35625
我已经为2组(data.frames)和data.frame输出编码了这个..但它可能会进一步推广......?