我有一个名为dat的数据帧,它看起来像这样:
id1 id2 value
1 3 0 8.00019752415226
2 4 0 27.4861843945884
3 0 3 8.00019752415226
4 4 3 20.1582815171649
5 0 4 27.4861843945884
6 3 4 20.1582815171649
7 1 2 0
8 2 1 0id1和id2可以取0到4的值,是对象的id号,值是每个对象之间的欧几里德距离。
现在我有了一个矩阵,它是通过一次取2个id变量的唯一元素(基本上是c(0,1,2,3,4))的所有可能的组合得到的:
combn(dat$id,2)它给出了输出:
> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
> [1,] 0 0 0 0 1 1 1 2 2 3
> [2,] 1 2 3 4 2 3 4 3 4 4现在我想根据这个矩阵的每一列在dat中选择行,即用(id1= 0,id2 = 1);(id1= 0,id2 = 2);(id1 = 0,id2 = 3)选择行,依此类推,并由它们组成一个数据帧。
现在我可以使用for循环轻松地实现这一点,但我想知道是否有更快、更优雅的方法来使用矢量化函数来实现这一点。提前感谢!
发布于 2021-03-26 19:13:33
尽管您的dat$id不可用,但我使用combn(0:4, 2)创建了我的you,您可以使用以下语法将其替换为combn(dat$id, 2)
purrr::map(as.data.frame(combn(0:4, 2)), ~ dat[dat$id1 == .[1] & dat$id2 == .[2],])
$V1
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V2
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V3
id1 id2 value
3 0 3 8.000198
$V4
id1 id2 value
5 0 4 27.48618
$V5
id1 id2 value
7 1 2 0
$V6
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V7
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V8
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V9
[1] id1 id2 value
<0 rows> (or 0-length row.names)
$V10
id1 id2 value
6 3 4 20.15828如果你想把每个组合作为列表中的一个单独的项目,上面的代码将会起作用。但是,如果您想要组合所有这些,只需使用map_dfr而不是map
purrr::map_dfr(as.data.frame(combn(0:4, 2)), ~ dat[dat$id1 == .[1] & dat$id2 == .[2],])
id1 id2 value
3 0 3 8.000198
5 0 4 27.486184
7 1 2 0.000000
6 3 4 20.158282https://stackoverflow.com/questions/66814673
复制相似问题