igraph has a bipartite layout that tries to minimize edge crossings. You could run this layout, extract the coordinates, then wrap them around a circle.
I am not experienced enough with R to be able to afford the time to show you how this is done with the R interface. But I can show you what it would look like when you're done, using the Mathematica interface of igraph.
<< IGraphM`
IGraph/M 0.3.103 (November 13, 2018)
Evaluate IGDocumentation[] to get started.
Generate a sparse random bipartite graph, take its largest connected component, and run the layout. If the graph is not sparse, it won't be possible to avoid edges passing through the middle of the circle.
IGSeedRandom[4];
bg = IGGiantComponent@IGBipartiteGameGNM[100, 100, 220];
bg = IGLayoutBipartite[bg, "BipartitePartitions" -> IGBipartitePartitions[bg]]

Extract the coordinates, and wrap them around two circles.
pts = GraphEmbedding[bg]; (* get vertex coordinates *)
{m1, m2} = Max /@ Values@GroupBy[pts, First -> Last]; (* find max coordinate for both vertex groups *)
newPts = If[#1 == -1,
2 {Cos[#2/m1 2 Pi], Sin[#2/m1 2 Pi]},
3 {Cos[#2/m2 2 Pi], Sin[#2/m2 2 Pi]}
] & @@@ pts; (* wrap both groups around a circle *)
Graph[VertexList[bg], EdgeList[bg], VertexCoordinates -> newPts]

The above uses a circle radius ratio of 3:2. The bigger the radius ratio, the fewer edges cross the inner circle. Here's a plot with a ratio of 3:1.
