Как установить несколько условий для нескольких значений в строке в R? - PullRequest
0 голосов
/ 10 марта 2020

У меня есть набор данных geneti c, где каждая строка описывает ген и имеет столбец бета с несколькими значениями бета, которые я сжал в одну строку / ячейку (из уровня вариантов, где несколько вариантов в одном гене дали несколько бета-версий ). Бета - это величина эффекта, которую ген может оказать на состояние, поэтому важны как большие отрицательные значения, так и большие положительные значения. Я пытаюсь написать код, который выбирает либо наибольшее отрицательное, либо наибольшее положительное бета-значение для гена, обрезая его до -0,5 и 0,5.

Правила, которые я пытаюсь кодировать, таковы:

Если ген / строка имеет значение меньше -0,5 и нет значений выше 0,5, оставьте только самое большое отрицательное значение.

Если оно имеет значение выше 0,5 и нет значений меньше -0,5, сохраните только наибольшее положительное значение.

Если оно не имеет значений меньше -0,5 или больше 0,5, сохраняйте наибольшее значение.

Если оно имеет оба значения меньше -0,5 и больше 0,5, сохраняйте наибольшее значение.

Например, мои данные выглядят так:

Gene    Beta(s)
ACE     0.01, -0.6, 0.4
BRCA    0.7, -0.2, 0.2 
ZAP70   0.001, 0.02, -0.003
P53     0.8, -0.6, 0.001

Ожидаемый результат (выбор наибольшего отрицательного или положительного значения в зависимости от заданных условий):

Gene    Beta(s)
ACE     -0.6  
BRCA     0.7
ZAP70    0.02
P53      0.8   

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

max2 = function(x) if(all(is.na(x))) NA else max(x,na.rm = T)
getmax = function(col) str_extract_all(col,"[0-9\\.-]+") %>%
  lapply(.,function(x)max2(as.numeric(x)) ) %>%
  unlist() 

min2 = function(x) if(all(is.na(x))) NA else min(x,na.rm = T)
getmin = function(col) str_extract_all(col,"[0-9\\.-]+") %>%
  lapply(.,function(x)min2(as.numeric(x)) ) %>%
  unlist() 

test <- df %>%
  mutate_at(names(df)[2],getmax)

Любая помощь в правильном направлении как установить несколько условных операторов.

Пример данных:

 dput(df)
structure(list(Gene = c("ACE", "BRCA", "ZAP70", "P53"), `Beta(s)` = c("0.01, -0.6, 0.4", 
"0.7, -0.2, 0.2", "0.001, 0.02, -0.003", "0.8, -0.6, 0.001")), row.names = c(NA, 
-4L), class = c("data.table", "data.frame"))

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

Вот решение data.table, которое должно работать быстро и независимо от количества предоставляемых бета-версий.

library( data.table )
library( matrixStats ) 
#set df as data.table
setDT( df )
#split Beta(s) to columns (dynamically)
df[, paste0( "Beta", 
             1:length( tstrsplit( df$`Beta(s)`, "," ) ) ) := 
     lapply( tstrsplit( `Beta(s)`, "," ), as.numeric ) ][]
#     Gene             Beta(s) Beta1 Beta2  Beta3
# 1:   ACE     0.01, -0.6, 0.4 0.010 -0.60  0.400
# 2:  BRCA      0.7, -0.2, 0.2 0.700 -0.20  0.200
# 3: ZAP70 0.001, 0.02, -0.003 0.001  0.02 -0.003
# 4:   P53    0.8, -0.6, 0.001 0.800 -0.60  0.001


#now, using rowMINs ans RowMAxs from the matrixStats-package (=FAST!!)
# get the filtering (and updating) done by reference.

#If a gene/row has a value less than -0.5 and no values higher than 0.5 then keep only the largest negative value.
df[ df[, rowMins( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] < -0.5 &
      df[, rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] <= 0.5,
    Beta.final := rowMins( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ]
#If it has a value higher than 0.5 and no values less than -0.5 keep only the largest positive value.
df[ df[, rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] > 0.5 &
      df[, rowMins( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] >= -0.5,
    Beta.final := rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ]
#If it has no values less than -0.5 or more than 0.5 keep the largest value.
df[ df[, rowMins( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] >= -0.5 &
      df[, rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] <= 0.5,
    Beta.final := rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ]
#If it has both values less than -0.5 and more than 0.5 keep the largest value.
df[ df[, rowMins( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] < -0.5 &
      df[, rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ] > 0.5,
    Beta.final := rowMaxs( as.matrix(.SD), na.rm = TRUE ), .SDcols = patterns("^Beta[0-9]") ]

* выход

#final output
df[, .(Gene, `Beta(s)` = Beta.final )][]
#     Gene Beta(s)
# 1:   ACE   -0.60
# 2:  BRCA    0.70
# 3: ZAP70    0.02
# 4:   P53    0.80
1 голос
/ 10 марта 2020

Хотя логика c мне не совсем понятна, скорее всего что-то вроде этого:

library(tidyverse)
library(stringr)

df %>%
  separate("Beta(s)", sep = ",", into = str_c("v", 1:3)) %>%
  mutate_at(vars(starts_with("v")), as.numeric) %>%
  mutate(vmax = pmax(v1, v2, v3), vmin = pmin(v1, v2, v3)) %>%
  mutate(want = case_when(vmax > 0.5 & vmin > -0.5 ~ vmax, # if vmax is > 0.5, it is always positive ..
                          abs(vmax) > abs(vmin) ~ vmax, # get largest absolute value ??
                          TRUE ~ vmin)) %>%
  select(Gene, want)


# Gene  want
# 1   ACE -0.60
# 2  BRCA  0.70
# 3 ZAP70  0.02
# 4   P53  0.80

## edited (handling multiple columns and NA):

df %>%
  bind_cols(df %>% 
              pull("Beta(s)") %>%
              str_split(",", simplify = TRUE) %>%
              `colnames<-`(str_c("v", 1:NCOL(.))) %>%
              as_tibble() %>%
              mutate_all(~str_remove_all(., "\\s") %>%
                           str_remove_all(., "NA") %>%
                           as.numeric) %>%
              mutate(vmax = pmap_dbl(., pmax, na.rm = T),
                     vmin = pmap_dbl(., pmin, na.rm = T))) %>%
  mutate(want = case_when(vmax > 0.5 & vmin > -0.5 ~ vmax, 
                          abs(vmax) > abs(vmin) ~ vmax, 
                          TRUE ~ vmin)) %>%
  select(Gene, want)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...