R:如果值满足特定条件,如何将数据框转换为邻接矩阵?

R: How do I transform a data frame into an adjacency matrix if values meet a certain condition?

我有一个数据集,我想使用 R 查询并转换为邻接矩阵。

示例数据集如下:

> track_df
     track  sound start   end
1  track1A    car  1000  2000
2  track1A person  1200  1500
3  track1A    car  1500  1700
4  track1A    dog  2300  3000
5  track1B    cat  5000  8000
6  track1B    car  5500  8500
7  track1B    car  7500 10000
8  track1B person  8000  9000
9  track1C    dog  1300  1600
10 track1C    car  1500  1800
11 track1C person  1700  2000

该示例显示了录制在轨道上的声音以及每个声音的开始和结束时间。曲目包含多种声音。

生成示例的代码:

> track <- c('track1A', 'track1A', 'track1A', 'track1A', 'track1B', 'track1B', 'track1B', 'track1B', 'track1C', 'track1C', 'track1C')
> sound <- c('car', 'person', 'car', 'dog', 'cat', 'car', 'car', 'person', 'dog', 'car', 'person')
> start <- c(1000, 1200, 1500, 2300, 5000, 5500, 7500, 8000, 1300, 1500, 17000)
> end <- c(2000, 1500, 1700, 3000, 8000, 8500, 10000, 8000, 1300, 1500, 1700)
> end <- c(2000, 1500, 1700, 3000, 8000, 8500, 10000, 900, 1600, 1800, 2000)
> track_df <- data.frame(track, sound, start, end)

使用上面的数据集,我需要找到两个声音 overlap/intersect 的次数(基于它们的开始和结束时间)。

如果一个声音在轨道内的另一个声音期间开始或结束,则视为重叠。

所需的输出应该是这样的,我可以将其转换为热图或网络。

> matrix
       car person dog cat
car      2      4   1   2
person   4      0   0   0
dog      1      0   0   0
cat      2      0   0   0

我不确定处理此问题的最佳方法是什么,或者将初始数据集转换为可以轻松迭代和比较的内容的最佳方法是什么。

也许我可以使用 dplyrgroup_by track 然后 summarise 使用单独的函数来创建输出矩阵?我不确定我是否完全理解 summarise 的工作原理以及它是否会遍历 tracksounds 的每个组合。

如有任何帮助,我们将不胜感激。

我只能提供一个非矢量化的解决方案,它实际上确实迭代音轨中的每个声音组合 =16=].

track <- c('track1A', 'track1A', 'track1A', 'track1A', 'track1B', 'track1B', 'track1B', 'track1B', 'track1C', 'track1C', 'track1C')
sound <- c('car', 'person', 'car', 'dog', 'cat', 'car', 'car', 'person', 'dog', 'car', 'person')
start <- c(1000, 1200, 1500, 2300, 5000, 5500, 7500, 8000, 1300, 1500, 1700)
end <- c(2000, 1500, 1700, 3000, 8000, 8500, 10000, 9000, 1600, 1800, 2000)
track_df <- data.frame(track, sound, start, end)
names = levels(track_df$sound)
m = matrix(0, length(names), length(names), F, list(names, names))
for (track in split(track_df, track_df$track))
{
    n = nrow(track)
    for (i in 1:(n-1)) for (j in (i+1):n)
        if (track[i,]$start < track[j,]$end)
        if (track[j,]$start < track[i,]$end)
            m[track[j,]$sound, track[i,]$sound] =
            m[track[i,]$sound, track[j,]$sound] =
            m[track[i,]$sound, track[j,]$sound] + 1
}
print(m)