0

I have two dataframes (nodes and edges). nodes data frame contains x and y coordinaates for nodes (which are essentially atoms) and atom numbers. edges dataframe contains x_start x_end and y_start y_end for edges to connect specific atoms (i.e. bonds). I am wondering if there is any way using R to tell which atoms (which atom numbers) belong to the ring.

For example in the plot, atoms 6,4,5,8,19,18 and 9,7,2,20,24,21 form the ring. Because I have coordinates of thousands of molecules, instead of manually checking I was wondering if there is a way to detect which atoms belong to the ring structure. Rings can be different in size than example plot (e.g. different number of atoms) and different composition (not necessarily carbons)

any help will be much appreciated, thanks in advance

edges <- structure(list(edge_from = c(2L, 3L, 4L, 5L, 9L, 10L, 11L, 12L, 
13L, 14L, 15L, 16L, 17L, 19L, 20L, 21L, 22L, 23L, 18L, 6L, 6L, 
7L, 7L, 8L, 8L, 18L, 18L, 24L, 24L, 21L, 21L), edge_to = c(1L, 
6L, 5L, 16L, 7L, 1L, 1L, 1L, 3L, 3L, 3L, 22L, 7L, 8L, 2L, 24L, 
23L, 17L, 6L, 4L, 4L, 2L, 2L, 5L, 5L, 19L, 19L, 20L, 20L, 9L, 
9L), n_bonds = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), x_start = c(3.789674, -4.197826, -2.872826, 
-2.872826, 5.114674, 0.952174, 1.239674, 2.197974, -4.193726, 
-2.947826, -5.443726, -1.535326, 2.460474, -5.527026, 5.114674, 
6.439674, -0.210326, 1.127174, -5.527026, -4.197826, -4.27811279554577, 
3.789674, 4.029008, -4.197826, -4.27846455694268, -5.527026, 
-5.287692, 6.439674, 6.35974852787204, 6.439674, 6.35903544305732
), y_start = c(-2.181736, 3.964064, 1.651564, 0.118264, 0.126564, 
-2.381736, -3.656736, -4.535936, 5.347464, 4.959964, 4.968264, 
-0.656736, 0.126564, 0.118264, -2.948436, -0.648436, 0.118264, 
-0.648436, 1.651564, 2.422464, 2.26341679554577, -0.648436, -0.648436, 
-0.656736, -0.498040556942684, 1.651564, 1.651564, -2.181736, 
-2.02232747212796, -0.648436, -0.807131443057316), x_end = c(2.452174, 
-4.197826, -2.872826, -1.535326, 3.789674, 2.452174, 2.452174, 
2.452174, -4.197826, -4.197826, -4.197826, -0.210326, 3.789674, 
-4.197826, 3.789674, 6.439674, 1.127174, 2.460474, -4.197826, 
-2.872826, -2.95311279554577, 3.789674, 4.029008, -2.872826, 
-2.95346455694268, -5.527026, -5.287692, 5.114674, 5.03474852787204, 
5.114674, 5.03403544305732), y_end = c(-2.948436, 2.422464, 0.118264, 
-0.656736, -0.648436, -2.948436, -2.948436, -2.948436, 3.964064, 
3.964064, 3.964064, 0.118264, -0.648436, -0.656736, -2.181736, 
-2.181736, -0.648436, 0.126564, 2.422464, 1.651564, 1.49251679554577, 
-2.181736, -2.181736, 0.118264, 0.276959443057316, 0.118264, 
0.118264, -2.948436, -2.78902747212796, 0.126564, -0.0321314430573162
)), row.names = c(NA, -31L), class = "data.frame")

nodes <- structure(list(X = c(2.452174, 3.789674, -4.197826, -2.872826, 
-2.872826, -4.197826, 3.789674, -4.197826, 5.114674, 0.952174, 
1.239674, 2.197974, -4.193726, -2.947826, -5.443726, -1.535326, 
2.460474, -5.527026, -5.527026, 5.114674, 6.439674, -0.210326, 
1.127174, 6.439674), Y = c(-2.948436, -2.181736, 3.964064, 1.651564, 
0.118264, 2.422464, -0.648436, -0.656736, 0.126564, -2.381736, 
-3.656736, -4.535936, 5.347464, 4.959964, 4.968264, -0.656736, 
0.126564, 1.651564, 0.118264, -2.948436, -0.648436, 0.118264, 
-0.648436, -2.181736), atom = c("C", "C", "C", "N", "C", "C", 
"C", "N", "N", "F", "F", "F", "F", "F", "F", "N", "N", "C", "C", 
"C", "C", "C", "C", "C"), atom_n = 1:24), class = "data.frame", row.names = c(NA, 
-24L))

library(ggplot2)
ggplot(data = nodes, aes(x = X, y = Y))+
  geom_text(aes(label = atom_n, size = 3), color = "red", show.legend = F)+
  geom_segment(data = edges, aes(x = x_start, y = y_start, xend = x_end, yend = y_end))+
  theme_void()
  • This [answer](https://stackoverflow.com/a/55094319/4821142) contains a function called `FindCycles()`. If you convert your data into an `igraph` object you can use that function to get the nodes that are part of rings. – Till Jul 18 '23 at 13:54
  • @Till That answer will find all cycles in a graph, whatever the size and composition. I believe the OP wants to find C6 rings. – ravenspoint Jul 18 '23 at 14:04
  • Thank you very much! no, in fact I would like to find any ring regardless of the size (and even composition) in the example it was C6 rings and I did not specify. I will try FindCylcles() and answer from @ravenspoint – Bachi Shashikadze Jul 18 '23 at 14:09
  • You should edit your question to clarify what rings you are looking for. – ravenspoint Jul 18 '23 at 14:20
  • Why did you remove the image of the molecule? – ravenspoint Jul 20 '23 at 16:00

0 Answers0