大数据帧:千元因素之间的“重复”t检验

时间:2018-05-12 23:09:13

标签: r loops apply t-test

我已经阅读了很多与数据争论和“重复”t-test相关的帖子,但我无法弄清楚在我的情况下实现它的方法。

您可以在此处获取StackOverflow的示例数据集:https://www.dropbox.com/s/0b618fs1jjnuzbg/dataset.example.stckovflw.txt?dl=0

我有一个gen表达式的大数据框,如:

> b<-read.delim("dataset.example.stckovflw.txt")

> head(b)
      animal            gen condition tissue    LogFC
1 animalcontrol1         kjhss1   control  brain 7.129283
2 animalcontrol1          sdth2   control  brain 7.179909
3 animalcontrol1     sgdhstjh20   control  brain 9.353147
4 animalcontrol1 jdygfjgdkydg21   control  brain 6.459432
5 animalcontrol1  shfjdfyjydg22   control  brain 9.372865
6 animalcontrol1      jdyjkdg23   control  brain 9.541097

> str(b)
'data.frame':   21507 obs. of  5 variables:
 $ animal   : Factor w/ 25 levels "animalcontrol1",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ gen      : Factor w/ 1131 levels "dghwg1041","dghwg1086",..: 480 761 787    360 863 385 133 888 563 738 ...
 $ condition: Factor w/ 5 levels "control","treatmentA",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ tissue   : Factor w/ 2 levels "brain","heart": 1 1 1 1 1 1 1 1 1 1 ...
 $ LogFC    : num  7.13 7.18 9.35 6.46 9.37 ...

每组有5只动物,每只动物都有许多量化的动物。 (但是,每只动物可能有一组不同的量化基因,但许多动物也会在动物和群体之间共同存在)。

我想对我治疗组(A,B,C或D)和对照组之间的每一代进行t检验。数据应以表格形式显示,其中包含每组中每个基因的p值。

因为我有这么多一族(千人),所以我不能将每一代人分组。

你知道我怎么能自动化这个程序?

我在想循环,但我绝对不确定它能实现我想要的以及如何继续。

另外,我使用apply函数查看了这些帖子:Apply t-test on many columns in a dataframe split by factorLooping through t.tests for data frame subsets in r

# ###############在阅读第一条评论和答案后的附加信息:

@andrew_reece:非常感谢你。这几乎就是我想要的。但是,我找不到用t-test做的方法。 ANOVA是一个有趣的信息,但后来我需要知道哪些治疗组与我的对照有显着差异。另外,我需要知道哪个治疗组彼此显着不同,“两个两个”。

我一直试图通过更改“t.test(...)”中的“aov(..)”来使用您的代码。为此,首先我实现了一个子集(b,condition ==“control”| condition ==“treatmentA”),以便仅比较两个组。但是,在csv文件中导出结果表时,该表是不可理解的(没有gen名称,没有p值等,只有数字)。我会继续寻找正确的方法,但直到现在我都被卡住了。

@ 42:

非常感谢您提供这些建议。这只是一个数据集示例,我们假设我们必须使用单独的t检验。

这对于探索我的数据非常有用。例如,我一直试图用Venndiagrams来回复我的数据。我可以编写我的代码,但它有点偏离最初的主题。另外,我不知道如何以不那么挑剔的方式总结在每种条件组合中检测到的共享“基因”,所以我只用3个条件进行了简化。

# Visualisation of shared genes by VennDiagrams :
# let's simplify and consider only 3 conditions :

b<-read.delim("dataset.example.stckovflw.txt")
b<- subset(b, condition == "control" | condition == "treatmentA" | condition == "treatmentB")

b1<-table(b$gen, b$condition)

b1

b2<-subset(data.frame(b1, "control" > 2 
              |"treatmentA" > 2 
              |"treatmentB" > 2 ))

b3<-subset(b2, Freq>2) # select only genes that have been quantified in at     least 2 animals per group
b3
b4 = within(b3, {
  Freq = ifelse(Freq > 1, 1, 0)
}) # for those observations, we consider the gene has been detected so we     change the value 0 regardless the freq of occurence (>2)


b4

b5<-table(b4$Var1, b4$Var2)
write.csv(b5, file = "b5.csv")

# make an intermediate file .txt (just add manually the name of the cfirst     column title)
# so now we have info
bb5<-read.delim("bb5.txt")

nrow(subset(bb5, control == 1))
nrow(subset(bb5, treatmentA == 1))
nrow(subset(bb5, treatmentB == 1))

nrow(subset(bb5, control == 1 & treatmentA == 1))
nrow(subset(bb5, control == 1 & treatmentB == 1))
nrow(subset(bb5, treatmentA == 1 & treatmentB == 1))

nrow(subset(bb5, control == 1 & treatmentA == 1 & treatmentB == 1))

library(grid)
library(futile.logger)
library(VennDiagram)

venn.plot <- draw.triple.venn(area1 = 1005, 
                          area2 = 927, 
                          area3 = 943, 
                          n12 = 843, 
                          n23 = 861, 
                          n13 = 866, 
                          n123 = 794, 
                          category = c("controls", "treatmentA",     "treatmentB"),  
                          fill = c("red", "yellow", "blue"),
                          cex = 2,
                          cat.cex = 2,
                          lwd = 6,
                          lty = 'dashed',
                          fontface = "bold",
                          fontfamily = "sans",
                          cat.fontface = "bold",
                          cat.default.pos = "outer",
                          cat.pos = c(-27, 27, 135),
                          cat.dist = c(0.055, 0.055, 0.085),
                          cat.fontfamily = "sans",
                          rotation = 1);

enter image description here

1 个答案:

答案 0 :(得分:4)

更新(根据OP评论):
condition的成对比较可以通过ANOVA事后检验来管理,例如Tukey的诚实显着差异(stats::TukeyHSD())。 (还有其他人,这只是展示PoC的一种方式。)

results <- b %>%
  mutate(condition = factor(condition)) %>%
  group_by(gen) %>%
  filter(length(unique(condition)) >= 2) %>%
  nest() %>%
  mutate(
    model = map(data, ~ TukeyHSD(aov(LogFC ~ condition, data = .x))),
    coef = map(model, ~ broom::tidy(.x))
  ) %>%
  unnest(coef) %>% 
  select(-term)

    results
# A tibble: 7,118 x 6
   gen        comparison            estimate conf.low conf.high adj.p.value
   <chr>      <chr>                    <dbl>    <dbl>     <dbl>       <dbl>
 1 kjhss1     treatmentA-control       1.58     -20.3      23.5       0.997
 2 kjhss1     treatmentC-control      -3.71     -25.6      18.2       0.962
 3 kjhss1     treatmentD-control       0.240    -21.7      22.2       1.000
 4 kjhss1     treatmentC-treatmentA   -5.29     -27.2      16.6       0.899
 5 kjhss1     treatmentD-treatmentA   -1.34     -23.3      20.6       0.998
 6 kjhss1     treatmentD-treatmentC    3.95     -18.0      25.9       0.954
 7 sdth2      treatmentC-control      -1.02     -21.7      19.7       0.991
 8 sdth2      treatmentD-control       3.25     -17.5      24.0       0.909
 9 sdth2      treatmentD-treatmentC    4.27     -16.5      25.0       0.849
10 sgdhstjh20 treatmentC-control      -7.48     -30.4      15.5       0.669
# ... with 7,108 more rows

原始回答
您可以使用tidyr::nest()purrr::map()完成按gen分组的技术任务,然后进行比较condition的效果的统计测试(可能与LogFC作为你的DV)。

但我同意其他评论,你的统计方法存在问题需要仔细考虑 - stats.stackexchange.com是一个更好的论坛来解决这些问题。

出于演示的目的,我使用了ANOVA而不是t检验,因为每gen个分组通常有两个以上的条件。然而,这不应该真正改变实现背后的直觉。

require(tidyverse)

results <- b %>%
  mutate(condition = factor(condition)) %>%
  group_by(gen) %>%
  filter(length(unique(condition)) >= 2) %>%
  nest() %>%
  mutate(
    model = map(data, ~ aov(LogFC ~ condition, data = .x)),
    coef = map(model, ~ broom::tidy(.x))
  ) %>%
  unnest(coef) 

一些美容装饰可以更接近你原来的视觉(只有gen和p值的表格),但请注意,这确实留下了很多重要的信息,我不建议你实际上以这种方式限制你的结果。

results %>%
  filter(term!="Residuals") %>%
  select(gen, df, statistic, p.value)

results
# A tibble: 1,111 x 4
   gen               df statistic p.value
   <chr>          <dbl>     <dbl>   <dbl>
 1 kjhss1            3.     0.175   0.912
 2 sdth2             2.     0.165   0.850
 3 sgdhstjh20        2.     0.440   0.654
 4 jdygfjgdkydg21    2.     0.267   0.770
 5 shfjdfyjydg22     2.     0.632   0.548
 6 jdyjkdg23         2.     0.792   0.477
 7 fckjhghw24        2.     0.790   0.478
 8 shsnv25           2.     1.15    0.354
 9 qeifyvj26         2.     0.588   0.573
10 qsiubx27          2.     1.14    0.359
# ... with 1,101 more rows

注意:我不能对这种方法给予太多信任 - 我几乎逐字逐句地看到哈德利昨晚在purrr的演讲中给出的一个例子。以下是他使用的演示代码的公共回购a link,其中包含类似的用例。