我遇到了一个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。我想找到包含非零的行(或列),这些行也不在对角线上。
很抱歉发布了整个程序,我还想知道从起始数据框到使用条目中的交叉点是否有更短的方法。
答案 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