фильтровать строки, которые имеют одну или определенные складки

Я все еще изучаю R, у меня есть этот набор данных, в нем есть 5 столбцов, первый столбец - tracking_id, следующие четыре столбца имеют значения четырех групп.

Я хочу отфильтровать строки после сравнения последних трех столбцов (CD44hi_CD69low_rep, CD44hi_CD69hi_CD103low_rep, CD44hi_CD69hi_CD103hi_rep), которые в 8 раз больше или в 4 раза ниже по сравнению с столбцом (CD44low_rep).

Как этого добиться?


r
person user432797    schedule 27.11.2020    source источник
comment
Все столбцы @akrun   -  person user432797    schedule 28.11.2020


Ответы (1)


Мы умножаем столбец CD44low_rep на 8 и 4, затем сравниваем его с интересующими столбцами, используя >= и <= соответственно, получаем строчную сумму ИСТИННЫХ значений с помощью rowSums, проверяем, равно ли оно 3 (т. Е. Количество сравниваемых столбцов ), используйте & для возврата одного логического вектора из обоих сравнений и используйте его для подмножества строк

nm1 <- c("CD44hi_CD69low_rep",  "CD44hi_CD69hi_CD103low_rep", 
         "CD44hi_CD69hi_CD103hi_rep")
i1 <- (rowSums(df1[nm1]  >= (df1$CD44low_rep * 8)) == 3) &
     (rowSums(df1[nm1]  <= (df1$CD44low_rep * 4)) == 3)

df1[i1,]
# A tibble: 798 x 5
#   tracking_id   CD44low_rep CD44hi_CD69low_rep CD44hi_CD69hi_CD103low_rep CD44hi_CD69hi_CD103hi_rep
#   <chr>               <dbl>              <dbl>                      <dbl>                     <dbl>
# 1 1600014C23Rik           0                  0                          0                         0
# 2 1600019K03Rik           0                  0                          0                         0
# 3 1700006E09Rik           0                  0                          0                         0
# 4 1700010M22Rik           0                  0                          0                         0
# 5 1700011A15Rik           0                  0                          0                         0
# 6 1700016P04Rik           0                  0                          0                         0
# 7 1700018G05Rik           0                  0                          0                         0
# 8 1700019A02Rik           0                  0                          0                         0
# 9 1700024B18Rik           0                  0                          0                         0
#10 1700024G13Rik           0                  0                          0                         0
# … with 788 more rows

Или, используя dplyr, мы используем то же выражение, перебирая интересующие столбцы с помощью across (по умолчанию он выполняет проверку для all столбцов)

library(dplyr)
df1 %>%
     filter(across(contains('hi'), ~ (. >= (CD44low_rep * 8)) & 
                (. <= (CD44low_rep * 4))))

-выход

# A tibble: 798 x 5
#   tracking_id   CD44low_rep CD44hi_CD69low_rep CD44hi_CD69hi_CD103low_rep CD44hi_CD69hi_CD103hi_rep
#   <chr>               <dbl>              <dbl>                      <dbl>                     <dbl>
# 1 1600014C23Rik           0                  0                          0                         0
# 2 1600019K03Rik           0                  0                          0                         0
# 3 1700006E09Rik           0                  0                          0                         0
# 4 1700010M22Rik           0                  0                          0                         0
# 5 1700011A15Rik           0                  0                          0                         0
# 6 1700016P04Rik           0                  0                          0                         0
# 7 1700018G05Rik           0                  0                          0                         0
# 8 1700019A02Rik           0                  0                          0                         0
# 9 1700024B18Rik           0                  0                          0                         0
#10 1700024G13Rik           0                  0                          0                         0
# … with 788 more rows
person akrun    schedule 27.11.2020
comment
Спасибо @akrun, чего-то не хватает в первом варианте, я получаю эту ошибку Error in parse(text = x, srcfile = src): <text>:35:60: unexpected ']' 34: i1 <- (rowSums(df1[nm1] >= (df1$CD44low_rep * 8)[col(df1[nm1])]) == 3) & 35: (rowSums(df1[nm1] <= (df1$CD44low_rep * 4)[col(df1[nm1]] ^ - person user432797; 28.11.2020
comment
@ user432797 теперь должно работать. Я внес изменения и забыл изменить это здесь - person akrun; 28.11.2020
comment
Большое спасибо @akrun, я сначала попытался отфильтровать из фрейма данных любое значение, равное или больше 1, я использовал df1 %>% select_if(is.numeric) %>% filter_all(all_vars(. >= 1)), затем я попробовал ваш код для фильтрации условия в вопросе (8 раз больше или 4 меньше), но у меня нет вывода! любое предложение? - person user432797; 28.11.2020
comment
@ user432797 Вероятно, в отфильтрованных данных у вас могут не соблюдаться оба условия, потому что ваши новые отфильтрованные данные содержат 7270 строк в отличие от исходных данных 23746 - person akrun; 28.11.2020
comment
@ user432797, если вы проверяете только первое условие, то будет 18 строк df2 %>% filter(across(contains('hi'), ~ (. >= (CD44low_rep * 8)))), где df2 - отфильтрованный. ТОГДА, когда вы совмещаете со вторым, у вас может не быть общего случая. Может быть вам нужно | условие вместо & - person akrun; 28.11.2020
comment
@ user432797, если это условие ИЛИ df2 %>% filter((across(contains('hi'), ~ (. >= (CD44low_rep * 8))))| (across(contains('hi'), ~ (. <= (CD44low_rep * 4))))) - person akrun; 28.11.2020
comment
Большое спасибо @Akrun, я получаю целые 23К строк после строки, я отправлю отдельный вопрос, подробно описывающий три условия вместе. - person user432797; 28.11.2020
comment
@ user432797 Я думаю, что это |, потому что вы не можете одновременно выполнять оба условия для одной и той же строки. - person akrun; 28.11.2020
comment
@ user432797, когда вы публикуете вопрос, можете ли вы сделать небольшой пример и его ожидаемый результат, чтобы мы могли легче его отслеживать - person akrun; 28.11.2020
comment
Я только что разместил вопрос с выводом, который я ищу stackoverflow.com/questions/65044999/ @akrun - person user432797; 28.11.2020
comment
@ user432797 Я это видел. Если мы заменим & на |, я получу 6944 строки из 7270. Каково ожидаемое количество строк - person akrun; 28.11.2020