2
$\begingroup$

I have to compare two star catalogs, the problem is that the names of stars are different in each catalog. For comparision, I have a third catalog with common names of each star. So I need to crosscheck two lists with a third and create a fourth containing all star properties. Im summary, consider the following catalogs:

hypatia={"HIP87382", "2MASS19290895+4311502", "HIP98314", "HIP98316", "HIP106931",...}
names={{"2259072226846681494447849441045193405", "HIP87382", "HD162826", 
  "BD+4003225B+4003225", "2MASS17511402+4004208", 
  "GaiaDR21344497769227698432", "TYC3093-01946-1", "HR06669", 
  "GaiaDR11344497764930721536"},...}

I need to create a list where each entry correspond to a list {i,j}, i beeing the position of name hypatia[[j]] in names list. I tried the following brute force method:

indhyp={}
Do[
 If[MemberQ[names[[i]], hypatia[[j]]], 
  indhyp = Append[indhyp, {i, j}]],
 {i, 1, Length[names]}, {j, 1, Length[hypatia]}
 ]

The problem is that this code returns the following:

{{1, 1612}, {1, 1613}, {4, 725}, {4, 726}, {4, 727}, {5, 1042},...}

As can be seen, the first two terms are repeated, meaning that both hypatia[[1612]] and hypatia[[1613]] appears in the position names[[1]]. That's wrong, as hypatia[[1612]] and hypatia[[1613]] are different stars with different names. I have no clue why. Is there any other non brute force method, or any clue why this problem is happening?

$\endgroup$
4
  • 1
    $\begingroup$ Please post a minimal working example. $\endgroup$
    – cvgmt
    Commented Aug 4, 2021 at 1:49
  • 2
    $\begingroup$ Consider poslist = Position[names, #] & /@ hypatia. This should give you a list of singletons, each containing the desired position specification; check that that's the case with MatchQ[poslist, {{{___}}...}]. If you get True, then you can safely take the first (and only) element of each: poslist = First /@ poslist But if you get False, let me know... $\endgroup$
    – thorimur
    Commented Aug 4, 2021 at 6:41
  • $\begingroup$ and just to be clear, we have both MatchQ[names, {{___String}...}] and MatchQ[hypatia, {___String}], right? $\endgroup$
    – thorimur
    Commented Aug 4, 2021 at 6:43
  • $\begingroup$ also: do you have some broader task you want to do with this resulting list of parts? there may be an easier way to cross-check them in mathematica...! $\endgroup$
    – thorimur
    Commented Aug 4, 2021 at 6:48

2 Answers 2

1
$\begingroup$

I am not sure if I understand your description correctly. You have a list with names in "hypatia". Then the same names appear in a list of lists named "names". And you want determine the indices of names from "hypatia" in the list of lists "names". The command "Position" will do the job. Here is an example:

For an example we create names from numbers:

hypatia = Table[ToString[i], {i, 100}];

We then split these names into a list of lists:

names = Partition[hypatia, 10];

You could additonally add names that do not appear in "hypatia", but for simplicity I am not doing this. Now `Position will give you the indices:

Flatten[Position[names, #]] & /@ hypatia

enter image description here

$\endgroup$
0
$\begingroup$
hypatia = {"HIP87382", "2MASS19290895+4311502", "HIP98314", "HIP98316", "HIP106931"};

A random list of names:

SeedRandom[1]

names = Table[RandomSample[#, 5] & @
    Union[{"2259072226846681494447849441045193405", "HIP87382", 
      "HD162826", "BD+4003225B+4003225", "2MASS17511402+4004208", 
      "GaiaDR21344497769227698432", "TYC3093-01946-1", "HR06669", 
      "GaiaDR11344497764930721536"}, hypatia], 10];

Column @ names

enter image description here

1. Using Outer:

poslist = Join @@ Outer[
   If[MemberQ[names[[#]], hypatia[[#2]]], {#, #2}, Nothing] &, 
   Range @ Length @ names, Range @ Length @ hypatia]
{{1, 4}, {1, 5}, {2, 1}, {3, 1}, {3, 3}, {4, 2}, {5, 2}, {7, 2},
 {8,  3}, {9, 2}, {9, 3}}

2. Using Tuples:

posF = If[MemberQ[names[[#]], hypatia[[#2]]], {#, #2}, Nothing] &;

poslist2 = posF @@@ Tuples[{Range @ Length @ names, Range @ Length @ hypatia}]
 {{1, 4}, {1, 5}, {2, 1}, {3, 1}, {3, 3}, {4, 2}, {5, 2}, {7, 2},
  {8, 3}, {9, 2}, {9, 3}}

3. Using MapIndexed + PositionIndex:

poslist3 = Join @@ MapIndexed[Join @@ 
  (Thread[{#2[[1]], PositionIndex[hypatia]@#}] /. {_, _Missing} :> Nothing) &, 
   names, {2}]
 {{1, 5}, {1, 4}, {2, 1}, {3, 1}, {3, 3}, {4, 2}, {5, 2}, {7, 2}, 
  {8, 3}, {9, 2}, {9, 3}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.