Использование пользовательской функции для применения в нескольких группах и подмножествах - PullRequest
1 голос
/ 24 марта 2019

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

Другими словами, среднее отрицательного контроля вычитается из экспериментального значения, затем делится на среднее отрицательного контроля минус положительный контроль.

Каждое наблюдение, включая + и - контроли, должно иметь вычисленный процент ингибирования, и в качестве двойной проверки для каждого эксперимента (группировки) среднее значение pct ингибирования - контролей должно быть около 0, а +контролирует около 100.

Функция:

percent_inhibition <- function(uninhibited, inhibited, unknown){

  uninhibited <- as.vector(uninhibited)
  inhibited <- as.vector(inhibited)
  unknown <- as.vector(unknown)

  mu_u <- mean(uninhibited, na.rm = TRUE)
  mu_i <- mean(inhibited, na.rm = TRUE)    

  percent_inhibition <- (mu_u - unknown)/(mu_u - mu_i)*100
  return(percent_inhibition)
}

У меня есть фрейм данных с несколькими переменными: цель, поле, копия и тип образца.Я могу выполнить вычисление путем поднабора данных (ниже), (1 цель, поле и копия), но не смог найти правильный способ применить его ко всем данным.

subset <- data %>% 
  filter(target == "A", box == "1", replicate == 1) 

uninhib <-  
  subset$value[subset$sample == "unihib"]

inhib <-
  subset$value[subset$sample == "inhib"]


pct <- subset %>% 
  mutate(pct = percent_inhibition(uninhib, inhib, .$value))

Я пытался использовать функции group_by, do и nest, но у меня недостаточно знаний о том, как применить эти функции к моей проблеме поднабора.Я застрял, когда дело доходит до подмножества подмножества (вычисление среднего значения), а затем применяя это к отдельным значениям.Я надеюсь, что есть элегантный способ сделать это без всего поднабора, но я не знаю, как это сделать.

Я пытался:

inhibition <- data %>%
  group_by(target, box, replicate) %>% 
  mutate(pct = (percent_inhibition(.$value[.$sample == "uninhib"], .$value[.$sample == "inhib"], .$value))) 

Но получите ошибку, котораястолбцы неправильной длины из-за функции group_by.

1 Ответ

1 голос
/ 25 марта 2019
library(tidyr)
library(purrr)
library(dplyr)

data %>%
  group_by(target, box, replicate) %>% 
  mutate(pct = {
    x <- split(value, sample)
    percent_inhibition(x$uninhib, x$inhib, value)
  }) 
#> # A tibble: 10,000 x 6
#> # Groups:   target, box, replicate [27]
#>    target box   replicate sample    value     pct
#>    <chr>  <chr>     <int> <chr>     <dbl>   <dbl>
#>  1 A      1             3 inhib   -0.836   1941. 
#>  2 C      1             1 uninhib -0.221   -281. 
#>  3 B      3             2 inhib   -2.10    1547. 
#>  4 C      1             1 uninhib -1.67   -3081. 
#>  5 C      1             3 inhib   -1.10   -1017. 
#>  6 A      2             1 inhib   -1.67     906. 
#>  7 B      3             1 uninhib -0.0495   -57.3
#>  8 C      3             2 inhib    1.56    5469. 
#>  9 B      3             2 uninhib -0.405    321. 
#> 10 B      1             2 inhib    0.786  -3471. 
#> # … with 9,990 more rows

Создан в 2019-03-25 пакетом представ (v0.2.1)

Или:

data %>%
  group_by(target, box, replicate) %>% 
  mutate(pct = percent_inhibition(value[sample == "uninhib"], 
                                  value[sample == "inhib"], value))

С data как:

n <- 10000L
set.seed(123) ; data <- 
  tibble(
    target = sample(LETTERS[1:3], n, replace = TRUE),
    box = sample(as.character(1:3), n, replace = TRUE),
    replicate = sample(1:3, n, replace = TRUE),
    sample = sample(c("inhib", "uninhib"), n, replace = TRUE),
    value = rnorm(n)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...