Вычесть значения из соответствующей группы - PullRequest
1 голос
/ 18 марта 2020

скажем, у меня есть следующая таблица:

data

df1 <- structure(list(sample = c("WT_mock", "WT_mock", "WT_mock", "WT_stim", 
"WT_stim", "WT_mock", "WT_mock", "WT_mock", "WT_stim", "WT_stim"
), target = c("ref", "goi1", "goi2", "goi1", "goi2", "ref", "goi1", 
"goi2", "goi1", "goi2"), replicate = c(1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L), mean = c(15L, 20L, 21L, 22L, 23L, 15L, 20L, 
21L, 22L, 23L)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6", "7", "8", "9", "10"))
# A tibble: 10 x 4
   sample  target replicate  mean
   <chr>   <chr>      <dbl> <dbl>
 1 WT_mock ref            1    15
 2 WT_mock goi1           1    20
 3 WT_mock goi2           1    21
 4 WT_stim goi1           1    22
 5 WT_stim goi2           1    23
 6 WT_mock ref            2    15
 7 WT_mock goi1           2    20
 8 WT_mock goi2           2    21
 9 WT_stim goi1           2    22
10 WT_stim goi2           2    23

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

# A tibble: 10 x 5
   sample  target replicate  mean   dCt
   <chr>   <chr>      <dbl> <dbl> <dbl>
 1 WT_mock ref            1    15     0
 2 WT_mock goi1           1    20    -5
 3 WT_mock goi2           1    21    -6
 4 WT_stim goi1           1    22    -7
 5 WT_stim goi2           1    23    -8
 6 WT_mock ref            2    15     0
 7 WT_mock goi1           2    20    -5
 8 WT_mock goi2           2    21    -6
 9 WT_stim goi1           2    22    -7
10 WT_stim goi2           2    23    -8

Я знаю, что есть несколько пакетов bioconductor, которые могут это сделать, но я хочу использовать это как упражнение в манипулировании данными с использованием R.

Мой подход заключался в filter для каждой реплики и вычитании значения ref «вручную», но я думаю, что есть более элегантный способ решения этой проблемы (dplyr et c.) Мой реальный набор данных имеет несколько копий и образцов, и мне интересно, есть ли более быстрый способ добиться этого.

Большое спасибо!

Ответы [ 2 ]

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

Вот некоторые базовые решения R:

  • Если у вас всегда есть ref в качестве первой строки в соответствующей группе, возможно, вы можете попробовать следующий код
df <- within(df,dCt<-ave(mean,replicate,FUN = function(x) head(x,1)-x))
  • В противном случае (ref - не первая строка в соответствующей группе)
df <- do.call(rbind,c(make.row.names = FALSE,
                      lapply(split(df,df$replicate),
                             function(v) within(v,dCt<-mean[target=="ref"]-mean))))

Обе из приведенных выше дают вам

> df
    sample target replicate mean dCt
1  WT_mock    ref         1   15   0
2  WT_mock   goi1         1   20  -5
3  WT_mock   goi2         1   21  -6
4  WT_stim   goi1         1   22  -7
5  WT_stim   goi2         1   23  -8
6  WT_mock    ref         2   15   0
7  WT_mock   goi1         2   20  -5
8  WT_mock   goi2         2   21  -6
9  WT_stim   goi1         2   22  -7
10 WT_stim   goi2         2   23  -8
2 голосов
/ 18 марта 2020

После группировки по «replicate» создайте «dCt», вычитая «среднее» из среднего значения, соответствующего значению «ref» в «target»

library(dplyr)
df1 %>%
    group_by(replicate) %>%
     mutate(dCt = mean[target == 'ref'] - mean)
# A tibble: 10 x 5
# Groups:   replicate [2]
#   sample  target replicate  mean   dCt
#   <chr>   <chr>      <int> <int> <int>
# 1 WT_mock ref            1    15     0
# 2 WT_mock goi1           1    20    -5
# 3 WT_mock goi2           1    21    -6
# 4 WT_stim goi1           1    22    -7
# 5 WT_stim goi2           1    23    -8
# 6 WT_mock ref            2    15     0
# 7 WT_mock goi1           2    20    -5
# 8 WT_mock goi2           2    21    -6
# 9 WT_stim goi1           2    22    -7
#10 WT_stim goi2           2    23    -8

или используя match

df1 %>% 
  group_by(replicate) %>%
  mutate(dCt = mean[match('ref', target)] - mean)

Или используя data.table

library(data.table)
setDT(df1)[, dCt := mean[match('ref', target)] - mean, by = replicate]

В base R мы также можем сделать

df1$dCt <-  with(df1,  mean[target == 'ref'][replicate] - mean)

data

df1 <- structure(list(sample = c("WT_mock", "WT_mock", "WT_mock", "WT_stim", 
"WT_stim", "WT_mock", "WT_mock", "WT_mock", "WT_stim", "WT_stim"
), target = c("ref", "goi1", "goi2", "goi1", "goi2", "ref", "goi1", 
"goi2", "goi1", "goi2"), replicate = c(1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L), mean = c(15L, 20L, 21L, 22L, 23L, 15L, 20L, 
21L, 22L, 23L)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6", "7", "8", "9", "10"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...