Извлечение строк по рангу и условию в R

#r #dataframe #conditional-statements #rank

#r #фрейм данных #условные операторы #ранг

Вопрос:

Я пытаюсь понять, как извлечь первые десять строк из таблицы на основе значений в одном числовом столбце, но только из строк, которые удовлетворяют условию, примененному ко второму числовому столбцу. столбец.
Сначала о данных. У меня есть таблица, в которой перечислены несколько тысяч человеческих генов, разница в экспрессии для элемента управления ( log_fold_change ) и p-значение для этой разницы ( p_value ). Таблица выглядит примерно так:

        log_fold_change   p_value
APOD         1.7388209 0.4820801
S100B       -1.1514299 0.5995658
CD63         0.6066951 0.4935413
PMEL        -1.4977796 0.1862176
MT2A        -0.9311173 0.8273733
S100A6      -0.4555436 0.6684667
TIMP1       -1.9464387 0.7942399
VIM         -0.4704482 0.1079436
PAEP         1.4787634 0.7237109
CSTB        -0.6386040 0.4112744
  

Данные могут быть воссозданы с помощью этих команд (создает таблицу с данными для n вымышленных генов):

 n <- 50    
log_fold_change <- runif(n, -2.0, 2.0)
p_value <- runif(n, 0, 1.0)  
df <- data.frame(log_fold_change, p_value)
rownames(df) <- stringi::stri_paste(stringi::stri_rand_strings(n, 3, '[A-Z]'),stringi::stri_rand_strings(n, 1, '[1-9]'))
  

Я создал столбец для labels ( df$label <- NA ) , в который я планирую перенести имена генов, которые я хочу пометить при построении своего графика. Какие гены, спросите вы? Я хочу, среди генов с положительным log_fold_change значением, извлечь десять генов с наименьшим p_value значением.

Я уже нашел способ извлечь и пометить 10 генов наименьшим p_value :

 df$label[with(df, rank(p_value)) %in% c(1:10)] <- rownames(df)[with(df, rank(p_value)) %in% c(1:10)]
  

Теперь, как мне обеспечить выполнение условия df$log_fold_change > 0 , чтобы мои десять генов с наименьшим p_value значением выбирались только из генов с положительным log_fold_change значением? Любая помощь будет очень признательна!

Ответ №1:

Сначала вы можете упорядочить свои данные, получить 10 значений where log_fold_change > 0 и перенести имена строк в label столбец.

 df <- df[order(df$log_fold_change), ]
inds <- which(df$log_fold_change > 0)[1:10]
df$label[inds] <- rownames(df)[inds]
  

Это сохранит ваш оригинал df таким, какой он есть, и у вас будет label только в этих 10 строках.

Если вам нужны только эти 10 строк, вы можете сделать :

 df1 <- df[inds, ]
  

Ответ №2:

dplyr решение:

 library(dplyr)

df %>%
  filter(log_fold_change > 0) %>%
  arrange(p_value) %>%
  head(10) %>%
  mutate(labels = rownames(.))
  

Вывод:

       A data.frame: 10 × 3
log_fold_change p_value label
   <dbl>       <dbl>    <chr>
0.9672121   0.01423086  MBT4
1.7139128   0.05044393  INQ3
0.4809652   0.10347463  ORW1
0.2949034   0.13493936  FVR2
0.9967781   0.17676960  JHP1
1.0813577   0.23599439  ITE9
1.0670343   0.25001069  ANQ4
1.5954271   0.26273176  XVL8
1.8803123   0.30065841  IQV6
0.3591054   0.46889062  JLD9
  

Сначала вы удаляете все наблюдения, которые меньше или равны 0 в log_fold_change столбце with filter(log_fold_change > 0) . Затем расположите p_value столбец в порядке возрастания с arrange(p_value) помощью и выберите первые 10 наблюдений с head(10) помощью . Наконец, создайте label столбцы с именами используемых генов mutate() . Это дает вам 10 наблюдений с наименьшим p_value значением, где log_fold_change оно положительное.

Ответ №3:

Используя базу R, этого можно достичь следующим образом:

  1. Разделите свой df на log_fold_change > 0 .
  2. Установите метки отдельно для каждого разделения
  3. Снова связать вместе
 n <- 50    
log_fold_change <- runif(n, -2.0, 2.0)
p_value <- runif(n, 0, 1.0)  
df <- data.frame(log_fold_change, p_value)
rownames(df) <- stringi::stri_paste(stringi::stri_rand_strings(n, 3, '[A-Z]'),stringi::stri_rand_strings(n, 1, '[1-9]'))

df_split <- split(df, df$log_fold_change > 0) 
df_split[["FALSE"]]$label <- NA
df_split[["TRUE"]]$label <- with(df_split[["TRUE"]], rank(-p_value))
df_split[["TRUE"]]$label <- ifelse(df_split[["TRUE"]]$label %in% 1:10, row.names(df_split[["TRUE"]]), NA)
df <- rbind(df_split[["FALSE"]], df_split[["TRUE"]])

df[!is.na(df$label),]
#>      log_fold_change   p_value label
#> IPQ1      1.46479105 0.9928132  IPQ1
#> GDA3      0.26974526 0.9696272  GDA3
#> CHU3      0.31643010 0.7094205  CHU3
#> IDE1      0.87836008 0.7152144  IDE1
#> KQJ9      1.12647503 0.7854047  KQJ9
#> FQM8      1.99924827 0.8463336  FQM8
#> RPO1      0.10874876 0.7279679  RPO1
#> TOA9      1.88312825 0.7143039  TOA9
#> EXG7      1.82497903 0.8082063  EXG7
#> RGE9      0.02894958 0.7685504  RGE9
  

Создано 2020-10-03 пакетом reprex (версия 0.3.0)