在数据框中查找交集条目

时间:2013-12-20 18:27:31

标签: r dataframe

我遇到了一个R编程问题,我似乎无法解决这个问题。我有以下数据:

data = data.frame("start"=c(1,2,4,5),
                  "length"=c(2,2,2,3),
                  "decision"=c("yes","no","yes","yes"))

看起来像:

  start length decision
1     1      2      yes
2     2      2       no
3     4      2      yes
4     5      3      yes

第一行代表一个整数序列,从1开始,长度为2(1,2)。第3行是从4(4,5)开始的2个整数。我正在寻找具有“是”决策变量的条目之间的交叉点。当决策变量为“否”时,则抛出序列。这是我到目前为止所做的尝试。

我想我需要先创建一个序列表。

sequence.list = lapply(seq(dim(data)[1]),
                       function(d){
                         seq(data$start[d],(data$start[d]+data$length[d]-1),by=1)
                         })

输出:

sequence.list
[[1]]
[1] 1 2

[[2]]
[1] 2 3

[[3]]
[1] 4 5

[[4]]
[1] 5 6 7

这是一个开始。然后我创建一个列表来计算列表中项目之间的交叉点(我从这里的另一篇文章中窃取了这个想法)。

count.intersect = lapply(sequence.list,function(a) {
  sapply(seq(length(sequence.list)), 
         function(b) length(intersect(sequence.list[[b]], a)))
  })

这会创建列表:

 count.intersect
[[1]]
[1] 2 1 0 0

[[2]]
[1] 1 2 0 0

[[3]]
[1] 0 0 2 1

[[4]]
[1] 0 0 1 3

读取此方法的方法是数据框中的条目1与自身有2个平凡的交叉点,与条目2有1个交叉点。

在这里我可以模糊地做什么。把它变成矩阵?

intersect.matrix = do.call(rbind,count.intersect)

然后将未使用的条目的行和列设置为零?

intersect.matrix[,data$decision=="no"]=0
intersect.matrix[data$decision=="no",]=0

intersect.matrix
     [,1] [,2] [,3] [,4]
[1,]    2    0    0    0
[2,]    0    0    0    0
[3,]    0    0    2    1
[4,]    0    0    1    3

现在,我想以某种方式返回索引3和4。我想找到包含非零的行(或列),这些行也不在对角线上。

很抱歉发布了整个程序,我还想知道从起始数据框到使用条目中的交叉点是否有更短的方法。

2 个答案:

答案 0 :(得分:0)

由于你对对角线上的非零值不感兴趣,首先我会将它们减去:

diag.mat <- diag(intersect.matrix) * diag(ncol(intersect.matrix)

给出:

intersect.matrix - diag.mat
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    0    0    0    1
[4,]    0    0    1    0

然后使用which确定哪些列仍包含非零条目:

which(colSums(intersect.matrix - diag.mat) != 0)
[1] 3 4

答案 1 :(得分:0)

您询问从数据框data到索引是否有很短的路要走。在这里。

(注意:如果你是R的新手,这可能很难理解。)

1)创建序列表:

sequence.list <- apply(data[1:2], 1, function(x) seq_len(x[2]) + x[1] - 1)
# [[1]]
# [1] 1 2
# 
# [[2]]
# [1] 2 3
# 
# [[3]]
# [1] 4 5
# 
# [[4]]
# [1] 5 6 7

2)计算相交并创建相交矩阵

intersect.matrix <- outer(s <- seq_along(sequence.list), s, 
                          Vectorize(function(a, b) 
                            length(Reduce(intersect, sequence.list[seq(a, b)]))))
#      [,1] [,2] [,3] [,4]
# [1,]    2    1    0    0
# [2,]    1    2    0    0
# [3,]    0    0    2    1
# [4,]    0    0    1    3

3)将与"no"对应的单元格设置为零

idx <- data$decision == "no"
intersect.matrix[idx, ] <- intersect.matrix[ , idx] <- 0
#      [,1] [,2] [,3] [,4]
# [1,]    2    0    0    0
# [2,]    0    0    0    0
# [3,]    0    0    2    1
# [4,]    0    0    1    3

4)查找非零行/列的索引(对角线除外)

result <- which(as.logical(colSums("diag<-"(intersect.matrix, 0))))
# [1] 3 4