@@ -65,6 +65,7 @@ fractionated = data.table::data.table(
6565 feature = rep(c(" A" , " B" ), each = 6 ),
6666 Fraction = rep(rep(c(1 , 2 ), each = 3 ), times = 2 ),
6767 Run = 1 : 12 ,
68+ IsotopeLabelType = " L" ,
6869 Intensity = c(NA , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 )
6970)
7071# ## More observations win
@@ -87,6 +88,7 @@ fractionated_third = data.table::data.table(
8788 feature = rep(" A" , 9 ),
8889 Fraction = c(rep(1 , 3 ), rep(2 , 3 ), rep(3 , 3 )),
8990 Run = 1 : 9 ,
91+ IsotopeLabelType = " L" ,
9092 Intensity = c(1 , 1 , 1 , # Fraction 1: 3 obs, mean = 1 (ties for max n_obs)
9193 2 , 2 , 2 , # Fraction 2: 3 obs, mean = 2 (ties for max n_obs)
9294 10 , NA , NA ) # Fraction 3: 1 obs, mean = 10 (loses on n_obs but mean would win w/o fix)
@@ -95,6 +97,47 @@ expect_equal(
9597 unique(MSstatsConvert ::: .removeOverlappingFeatures(fractionated_third )$ Fraction ),
9698 2
9799)
100+ # ## L/H isotope label types: fraction selection uses only L obs, output keeps both L and H;
101+ # ## NA-only features: fraction selection uses NA obs
102+ # Feature "A" (L+H): F1 has 1 L obs (run 1) + 4 H obs (runs 1-4) = 4 unique runs total
103+ # F2 has 3 L obs (runs 5-7) + 1 H obs (run 5) = 3 unique runs total
104+ # → If counting all unique runs: F1 wins (4 > 3)
105+ # → If counting L unique runs only: F2 wins (3 > 1)
106+ # → Expected: F2 selected, confirming H obs do not influence fraction selection
107+ # → Both L and H rows from F2 are returned
108+ # Feature "B" (NA only): F1 has 2 NA obs (runs 8-9), F2 has 4 NA obs (runs 10-13)
109+ # → NA obs: F1=2, F2=4 → F2 wins; all 4 F2 rows are kept
110+ fractionated_lh = data.table :: data.table(
111+ feature = c(rep(" A" , 9 ), rep(" B" , 6 )),
112+ Fraction = c(rep(1 , 5 ), rep(2 , 4 ),
113+ rep(1 , 2 ), rep(2 , 4 )),
114+ Run = c(1 , 1 , 2 , 3 , 4 , # A F1: run 1 paired L+H, runs 2-4 H only
115+ 5 , 5 , 6 , 7 , # A F2: run 5 paired L+H, runs 6-7 L only
116+ 8 , 9 , 10 , 11 , 12 , 13 ),
117+ IsotopeLabelType = c(" L" , " H" , " H" , " H" , " H" , # A F1: 1 L, 4 H
118+ " L" , " H" , " L" , " L" , # A F2: 3 L, 1 H
119+ rep(NA_character_ , 6 )),
120+ Intensity = rep(1 , 15 )
121+ )
122+ # ## Feature A: F1 has more total obs but fewer L obs — F2 must win to confirm L-only logic
123+ expect_equal(
124+ unique(MSstatsConvert ::: .removeOverlappingFeatures(fractionated_lh [feature == " A" ])$ Fraction ),
125+ 2
126+ )
127+ # ## Both L and H rows are returned for the winning fraction
128+ expect_true(
129+ all(c(" L" , " H" ) %in% MSstatsConvert ::: .removeOverlappingFeatures(fractionated_lh [feature == " A" ])$ IsotopeLabelType )
130+ )
131+ # ## Feature B (NA only) selected via NA obs count
132+ expect_equal(
133+ unique(MSstatsConvert ::: .removeOverlappingFeatures(fractionated_lh [feature == " B" ])$ Fraction ),
134+ 2
135+ )
136+ # ## Full dataset: A keeps F2 (L+H rows), B keeps F2 (NA rows)
137+ expect_identical(
138+ MSstatsConvert ::: .removeOverlappingFeatures(data.table :: copy(fractionated_lh )),
139+ fractionated_lh [(feature == " A" & Fraction == 2 ) | (feature == " B" & Fraction == 2 )]
140+ )
98141fractionated_tmt = fractionated = data.table :: data.table(
99142 feature = rep(c(" A" , " B" ), each = 6 ),
100143 Fraction = rep(rep(c(1 , 2 ), each = 3 ), times = 2 ),
0 commit comments