Как получить абсолютное значение, отметив, если число было отрицательным? - PullRequest
1 голос
/ 11 марта 2020

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

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

Gene    Beta
ACE     0.01, -0.6, 0.4
BRCA    0.7, -0.2, 0.2 
ZAP70   NA
P53     0.8, -0.6, 0.001

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

Gene    Beta     Negatives
ACE      0.6         1
BRCA     0.7         0
ZAP70    NA          NA
P53      0.8         0

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

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

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

#Outputs:
 Error in abs(x, na.rm = T) : 2 arguments passed to 'abs' which requires 1 

Любая помощь о том, как просто получить абсолютное значение в ячейка / строка была бы оценена, поскольку я предполагаю, что я мог бы также сделать столбец, получающий наибольшее отрицательное значение, сопоставить его с идентичными абсолютными значениями и использовать его в качестве моей записи отрицательных значений.

Входные данные:

dput(df)
structure(list(Gene = c("ACE", "BRCA", "ZAP70", "P53"), `Beta` = 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"))

Ответы [ 3 ]

4 голосов
/ 11 марта 2020

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

sapply(strsplit(df$Beta, ', '), function(i){i1 <- as.numeric(i); 
                                            i2 <- which.max(abs(i1));
                                         if (length(i2) == 0){NA}else{i[i2] < 0}}) * 1

#[1]  1  0 NA  0
3 голосов
/ 11 марта 2020

Одним из способов использования dplyr является получение значения через запятую в отдельных строках, group_by Gene получение абсолютного значения max Beta и проверка, является ли это значение отрицательным.

library(dplyr)

df %>%
  tidyr::separate_rows(Beta, sep = ",", convert = TRUE) %>%
  group_by(Gene) %>%
  summarise(Negatives = +(min(Beta) == -max(abs(Beta))),
            Beta = max(abs(Beta), na.rm = TRUE))

# A tibble: 4 x 3
#  Gene  Negatives   Beta
#  <fct>     <int>  <dbl>
#1 ACE           1    0.6
#2 BRCA          0    0.7
#3 P53           0    0.8
#4 ZAP70        NA   -Inf  

данные

df <- structure(list(Gene = structure(c(1L, 2L, 4L, 3L), .Label = c("ACE", 
"BRCA", "P53", "ZAP70"), class = "factor"), Beta = structure(c(1L, 
2L, NA, 3L), .Label = c("0.01, -0.6, 0.4", "0.7, -0.2, 0.2", 
"0.8, -0.6, 0.001"), class = "factor")), class = "data.frame", 
row.names = c(NA, -4L))
2 голосов
/ 11 марта 2020

Вы можете написать свою пользовательскую функцию f и векторизовать ее через Vectorize, то есть

f <- Vectorize(function(x) {
  v <- as.numeric(unlist(strsplit(as.character(x),split = ",")))
  c(Beta = max(abs(v)),Negatives = sum(v<0 & v==-max(abs(v))))
})

, а затем запустить

df <- cbind(df[1],t(f(df$Beta)))

так, чтобы

> df
   Gene Beta Negatives
1   ACE  0.6         1
2  BRCA  0.7         0
3 ZAP70   NA        NA
4   P53  0.8         0
...