Mehrere Indizes abgleichen
Ich habe einen großen Datensatz, in dem ich mehrere Proben in verschiedenen Tests und unter verschiedenen Bedingungen vergleichen muss. Ich suche nach einer Möglichkeit, diese einfach zu koppeln und zu analysieren. Nehmen wir als Beispiel an, ich habe Proben (S) a, b und c, die unter den Bedingungen (C) x, y und z den Tests (T) 1 und 2 unterzogen werden und die Ergebnisse (R) R1 und R2 ausgeben.
S T C R1 R2
a 1 x 2.9
a 1 y 2.6
a 1 z 8.7
a 2 x 9.4 0.372
a 2 y 8.1 0.208
a 2 z 7.6 0.154
b 1 x 7.5
b 1 y 7.3
b 1 z 1.7
b 2 x 3.9 0.213
b 2 y 7.9 0.435
b 2 z 2.5 0.294
c 1 x 6.2
c 1 y 1.8
c 1 z 6.3
c 2 x 1.5 0.246
c 2 y 6.0 0.496
c 2 z 1.7 0.167
Die Tests haben unterschiedliche Ausgänge, und ich muss je nach Test bestimmte Funktionen anwenden. Sowie:
Test1[a,b] = R1a/R1b
Test2[a,b] = R1a/R2a - R1b/R2b
Die Tests sollten nur auf Proben mit übereinstimmenden Bedingungen angewendet werden, aber jede Probe sollte gepaart werden. Ein Ergebnis wäre also:
S1 S2 T C R
a b 1 x 2.9/7.5
a c 1 x 2.9/6.2
a b 2 x 9.4/0.372-3.9/0.213
a c 2 x 9.4/0.372-1.5/0.246
a b 1 y 2.6/7.3
...
Ich habe eine Weile versucht, das richtig zu machen und mich am Ende selbst zu verwirren. Hat jemand eine Lösung oder Vorschläge? Wenn Sie ein leicht kopierbares Format des Beispiels wünschen:
{{S, T, C, R1, R2}, {a, 1, x, 2.9}, {a, 1, y, 2.6}, {a, 1, z, 8.7},
{a, 2, x, 9.4, 0.372}, {a, 2, y, 8.1, 0.208}, {a, 2, z, 7.6, 0.154},
{b, 1, x, 7.5}, {b, 1, y, 7.3}, {b, 1, z, 1.7}, {b, 2, x, 3.9, 0.213},
{b, 2, y, 7.9, 0.435}, {b, 2, z, 2.5, 0.294}, {c, 1, x, 6.2}, {c, 1, y, 1.8},
{c, 1, z, 6.3}, {c, 2, x, 1.5, 0.246}, {c, 2, y, 6., 0.496}, {c, 2, z, 1.7, 0.167}}
Antworten
Ich bin nicht sicher, ob ich richtig verstanden habe, welche Ergebnisse neu kombiniert werden sollen, aber dieser Code führt Folgendes aus: Zuerst werden die Daten nach Bedingung, dann nach Test gesammelt, dann werden Teilmengen der Länge 2 generiert und im letzten Schritt die numerische Berechnung der Ergebnisse wird angewandt:
test1[{{a_,1,c_,R1a_},{b_,1,c_,R1b_}}]:={a,b,1,c,R1a/R1b}
test2[{{a_,2,c_,R1a_,R2a_},{b_,2,c_,R1b_,R2b_}}]:={a,b,2,c,R1a/R2a-R1b/R2b}
{{S,T,C,R1,R2},{a,1,x,2.9},{a,1,y,2.6},{a,1,z,8.7},{a,2,x,9.4,0.372},{a,2,y,8.1,0.208},{a,2,z,7.6,0.154},{b,1,x,7.5},{b,1,y,7.3},{b,1,z,1.7},{b,2,x,3.9,0.213},{b,2,y,7.9,0.435},{b,2,z,2.5,0.294},{c,1,x,6.2},{c,1,y,1.8},{c,1,z,6.3},{c,2,x,1.5,0.246},{c,2,y,6.,0.496},{c,2,z,1.7,0.167}};
GatherBy[%,#[[3]]&][[2;;]];
Flatten[GatherBy[#,{x}\[Function]x[[2]]]&/@%,1];
Flatten[Subsets[#,{2}]&/@%,1];
If[#[[1,2]]===1,test1[#],test2[#]]&/@%;
%//TableForm
was dazu führt
a b 1 x 0.386667
a c 1 x 0.467742
b c 1 x 1.20968
a b 2 x 6.95896
a c 2 x 19.1713
b c 2 x 12.2123
a b 1 y 0.356164
a c 1 y 1.44444
b c 1 y 4.05556
a b 2 y 20.7814
a c 2 y 26.8455
b c 2 y 6.06415
a b 1 z 5.11765
a c 1 z 1.38095
b c 1 z 0.269841
a b 2 z 40.8472
a c 2 z 39.171
b c 2 z -1.67624
Dies ist nicht das erwartete Ergebnis OP, da es alle möglichen Teilmengen für einen bestimmten Test und eine bestimmte Bedingung enthält (z. B. den dritten Eintrag b, c Test 1 unter Bedingung x). Wenn es ein komplexeres Kriterium für die Kombination von Ergebnissen gibt, muss der Schritt, der die Teilmengen im obigen Code generiert, ersetzt / verfeinert werden. Verwenden von Subsequencesstatt Subsetsberücksichtigt nur geordnete Tupel, die die Lösung sein könnten, nach der OP sucht:
a b 1 x 0.386667
b c 1 x 1.20968
a b 2 x 6.95896
b c 2 x 12.2123
a b 1 y 0.356164
b c 1 y 4.05556
a b 2 y 20.7814
b c 2 y 6.06415
a b 1 z 5.11765
b c 1 z 0.269841
a b 2 z 40.8472
b c 2 z -1.67624
data = {{"S", "T", "C", "R1", "R2"}, {a, 1, x, 2.9}, {a, 1, y,
2.6}, {a, 1, z, 8.7}, {a, 2, x, 9.4, 0.372}, {a, 2, y, 8.1,
0.208}, {a, 2, z, 7.6, 0.154}, {b, 1, x, 7.5}, {b, 1, y, 7.3}, {b,
1, z, 1.7}, {b, 2, x, 3.9, 0.213}, {b, 2, y, 7.9, 0.435}, {b, 2,
z, 2.5, 0.294}, {c, 1, x, 6.2}, {c, 1, y, 1.8}, {c, 1, z,
6.3}, {c, 2, x, 1.5, 0.246}, {c, 2, y, 6., 0.496}, {c, 2, z, 1.7,
0.167}};
Grid[data, Dividers -> All, Background -> {None, 1 -> LightBlue},
Alignment -> {{Center, Center, Center, ".", "."}, Center}]
t1 = {#[[1]], #2[[1]], #[[2]], #[[3]], #[[4]]/#2[[4]]} &;
t2 = {#[[1]], #2[[1]], #[[2]], #[[3]], #[[4]]/#[[5]] - #2[[4]]/#2[[5]]} &;
proc = If[#[[1, 2]] === 1, t1 @@ #, t2 @@ #] &;
GroupByDaten von {test, condition}(Spalten 2 und 3) und verarbeiten 2-Teilmengen mit proc:
data2 = Join @@ Values @ GroupBy[Rest @ data, #[[{2, 3}]] &,
Map[proc] @ Subsets[#, {2}] &];
Grid[Prepend[{"S1", "S2", "T", "C", "R"}]@data2,
Dividers -> All, Background -> {None, 1 -> LightBlue},
Alignment -> {{Center, Center, Center, Center, "."}, Center}]
Alternativ können wir verwenden GatherBy:
data2 == Join @@ Map[Map[proc] @ Subsets[#, {2}]&] @ GatherBy[Rest@data, #[[{2, 3}]]&]
True