Создание новых зависимых от имени переменной столбцов в функции (чтобы указать уровни значимости в данных выражения) - PullRequest
0 голосов
/ 12 апреля 2019

В dfs, содержащих результаты дифференциально экспрессированных белков, я хотел бы отметить, какие белки превышают определенные пороги значимости (например, logFC> 1 & p <0,05 как up_0.05 или p <0.01 как up_0.01).Используя ifelse, я могу сделать это для каждого df отдельно, но было бы намного чётче иметь функцию, так как у меня много dfs для обработки таким образом. </p>

Был задан похожий вопрос ( dplyr - mutate: используйте имена динамических переменных ), но я не смог перевести это в решение моей проблемы, поэтому я был бы очень признателен, если бы вы могли исправить мой код функций для работы (пример данных предоставлен)

Спасибомного!

пример данных

p.vals <- seq(from=0, to=1, by=.0001)
logFCs <- seq(from=0, to=4, by=.1)


diffEx_proteins <- data.frame(protein=LETTERS[1:1000],
                          adj.P.Val=sample(p.vals, size=1000, replace=TRUE),
                          logFC=sample(logFCs, size=1000, replace=TRUE))

функция

mark_significants <- function(comparison){
comparison$paste0(comparison, "up_0.05") <- ifelse(comparison$adj.P.Val <= 0.05 & comparison$logFC >= 1, TRUE, FALSE)
comparison$paste0(comparison, "down_0.05") <- ifelse(comparison$adj.P.Val <= 0.05 & comparison$logFC <= -1, TRUE, FALSE)
comparison$paste0(comparison, "up_0.01") <- ifelse(comparison$adj.P.Val <= 0.01 & comparison$logFC >= 1, TRUE, FALSE)
comparison$paste0(comparison, "down_0.01") <- ifelse(comparison$adj.P.Val <= 0.01 & comparison$logFC <= -1, TRUE, FALSE)
}

использование

mark_significants(diffEx_proteins)

Я получаю ошибку «Ошибка в mark_significants (diffEx_proteins»)): недопустимая функция в сложном назначении "

Я хотел бы получить df с 4 добавленными логическими столбцами, указывающими, достигают ли более влажные белки заданные пороговые уровни.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2019

Несколько проблем с синтаксисом, который я объясню ниже.Вот фиксированная функция:

mark_significants <- function(comparison){
    comparison[,"up_0.05"] <- comparison$adj.P.Val <= 0.05 & comparison$logFC >= 1
    comparison[,"down_0.05"] <- comparison$adj.P.Val <= 0.05 & comparison$logFC <= -1
    comparison[,"up_0.01"] <- comparison$adj.P.Val <= 0.01 & comparison$logFC >= 1
    comparison[,"down_0.01"] <- comparison$adj.P.Val <= 0.01 & comparison$logFC <= -1
    return(comparison)
}

test <- mark_significants(diffEx_proteins)
head(test, 3)
#  protein adj.P.Val logFC up_0.05 down_0.05 up_0.01 down_0.01
#1       A    0.9612   1.4   FALSE     FALSE   FALSE     FALSE
#2       B    0.8271   3.1   FALSE     FALSE   FALSE     FALSE
#3       C    0.1829   2.5   FALSE     FALSE   FALSE     FALSE
  1. comparison - это data.frame, и поэтому функция paste0 не знает, что вставлять.По сути, он сопоставляет строки символов.Я предполагаю, что вы хотели добавить столбец, и в моем редакторе я использую квадратные скобки с новым именем.В отличие от вызова comparison$up_0.05, который также работал бы здесь, добавление нового столбца из квадратных скобок позволяет динамически именовать столбец - например, с помощью функции paste0.
  2. Функция ifelse ненеобходимо, если результат равен TRUE/FALSE и сравнение может быть непосредственно векторизовано из всего столбца.
  3. Наконец, переменные, измененные внутри функции, не изменяются вне ее, если не указано иное.Следовательно, мы должны указать R выводить результат функции через return.Чтобы напрямую изменить исходные данные, вы можете использовать diffEx_proteins <- mark_significants(diffEx_proteins).

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

Следуя дополнительной информации в комментарии, this и this сообщений предлагают решение.Короче говоря, имя data.frame должно быть извлечено до того, как данные поступят в функцию, в противном случае deparse(substitute()) возвращает целое data.frame.Здесь функция будет принимать имя data.frame как символьный вектор , get данные из имени и paste имя для имен столбцов результата.

mark_significants <- function(comparison){
    dat <- get(comparison)
    dat[,paste(comparison,"up_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC >= 1
    dat[,paste(comparison,"down_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC <= -1
    dat[,paste(comparison,"up_0.01", sep = "_")] <- dat$adj.P.Val <= 0.01 & dat$logFC >= 1
    dat[,paste(comparison,"down_0.01", sep = "_")] <- dat$adj.P.Val <= 0.01 & dat$logFC <= -1
    return(dat)
}

test1 <- mark_significants(deparse(substitute(diffEx_proteins)))
test2 <- mark_significants("diffEx_proteins")
identical(test1, test2)
# [1] TRUE
0 голосов
/ 16 апреля 2019

Рабочее, но не элегантное решение, разделяющее фрейм данных и его имя:

mark_significants_3 <- function(comparison, name){
 comparison[,paste0(name, "_up_0.05")] <- comparison$adj.P.Val <= 0.05 & 
comparison$logFC >= 1
 comparison[,paste0(name, "_down_0.05")] <- comparison$adj.P.Val <= 0.05 & c 
comparison$logFC <= -1
 comparison[,paste0(name, "_up_0.001")] <- comparison$adj.P.Val <= 0.001 & 
comparison$logFC >= 1
 comparison[,paste0(name, "_down_0.001")] <- comparison$adj.P.Val <= 0.001 & 
comparison$logFC <= -1
 return(comparison)
 } 

test3 <- mark_significants_3(diffEx_proteins, "diffEx_proteins")
0 голосов
/ 12 апреля 2019

Большое спасибо, ня, это привело меня на правильный путь к решению! Только я хотел добавить имя «сравнения» в новые столбцы, так как позже я использую имена столбцов для диаграммы VENN.

Вот моя модифицированная версия вашей функции, которая включает "сравнение" в имена столбцов (ваш совет о том, что сравнение является фреймом данных, помог решить его правильное использование)

mark_significants_2 <- function(comparison){
 comparison[,paste0("comparison","_up_0.05")] <- comparison$adj.P.Val <= 0.05 & comparison$logFC >= 1
 comparison[,paste0("comparison","_down_0.05")] <- comparison$adj.P.Val <= 0.05 & comparison$logFC <= -1
 comparison[,paste0("comparison","_up_0.01")] <- comparison$adj.P.Val <= 0.01 & comparison$logFC >= 1
 comparison[,paste0("comparison","_down_0.01")] <- comparison$adj.P.Val <= 0.01 & comparison$logFC <= -1
 return(comparison)
}

Постепенно я начинаю писать функции, ваши подсказки были великолепны для понимания проблем синтаксиса!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...