Для кадра данных с одинаковыми и разными числовыми значениями, как сохранить значения, которые, например, находятся дальше друг от друга, чем плюс или минус 0,05? - PullRequest
2 голосов
/ 14 мая 2019

Мне пришлось анализировать данные в отдельных экспериментах, поэтому я боюсь, что некоторые строки в моем фрейме данных - это одна и та же функция, хотя медианное значение m / z немного отличается.Я хочу иметь возможность ставить условие плюс / минус 0,05 для значений медианы m / z и сохранять только первый случай, когда это происходит.

В предоставленных данных x в качестве номера индекса, имя, котороепакет xcms предоставляет каждой функции на основе массы для зарядки и времени хранения, медианного значения m / z, которое я планирую отфильтровать (mzmed), и времени хранения в минутах.

length(unique(All_Isocratic$ordered_reporttab.name)) недостаточно, поскольку масса и время округлены до целых целых значений (M 293, T 51 секунда).Я думаю, что цикл for может работать, но я борюсь с тем, как сохранить весь фрейм данных для тех значений mzmed, которые удовлетворяют условию уникальности с точностью до плюс или минус 0,05 от других значений.

head(All_Isocratic, n = 10) 
    [X]         [ordered_reporttab.name]
1  1712                M293T51
2  2384                M315T44
3  1689                M160T52
4  1365                M169T50
5  1355                M204T44
6   971                 M69T35
7  1483               M293T52
8  1622                M130T53
9  2307                M199T34
10 1753               M293T51
       [mzmed] [Retention_Times]
1  293.08677       0.8481379
2  315.00825       0.7343729
3  160.06174       0.8743856
4  169.06872       0.8410968
5  204.06996       0.7400242
6   68.98316       0.5831329
7  293.10242       0.8522436
8  130.06592       0.8852018
9  198.94047       0.5662835
10 293.06542       0.8421682

Мой ожидаемый результат будет выглядеть примерно так: я бы не ожидал, что строки 7 и 10 выживут в процессе фильтрации.

head(All_Isocratic, n = 8) 
    [X]         [ordered_reporttab.name]
1  1712                M293T51
2  2384                M315T44
3  1689                M160T52
4  1365                M169T50
5  1355                M204T44
6   971                 M69T35
7  1622                M130T53
8  2307                M199T34
       [mzmed] [Retention_Times]
1  293.08677       0.8481379
2  315.00825       0.7343729
3  160.06174       0.8743856
4  169.06872       0.8410968
5  204.06996       0.7400242
6   68.98316       0.5831329
7  130.06592       0.8852018
8  198.94047       0.5662835

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Вы можете просто округлить до первого знака после запятой, который удовлетворяет вашему условию. Ваш код будет просто

answer = All_Isocratic[!duplicated(round(All_Isocratic$mzmed,1)),]

редактировать

Надеюсь, если ваши данные не слишком велики, вы можете обойтись без этого цикла

mzmed = All_Isocratics$mzmed
trues = rep(TRUE,length(mzmed))            # vector of logical, all TRUE
for (i in 1:length(mzmed)){                # loop through nrow of dataframe
  if (trues[i]){                           # if value has not been discarded, use as reference
      el = which(abs(mzmed[i]-mzmed)<0.05) # which values are in a +-0.05 range from reference
      trues[el[el!=i]]=FALSE               # turn values in range (except for the reference itself) to FALSE
  }
}
result = All_Isocratics[trues,]
0 голосов
/ 14 мая 2019

Я бы рассмотрел использование dplyr.Поскольку вы хотите устранить те, которые находятся в пределах 0,05 от mzmed, я бы arrange сначала проверил:

library(dplyr)
data %>% 
arrange(mzmed) %>%
mutate(check = if_else(abs(lag(mzmed, default = 0) - mzmed)) <= 0.05, 1, 0)) %>%
filter(check != 1)

Не уверен, имеет ли значение порядок (например, удержание наибольшего mzmed или наименьшего * 1008)* значение).Если этого не произойдет, это будет работать, в противном случае вам, возможно, придется также создать другой способ arrange данных.

...