Fisher对大型数据帧中的值进行精确测试并绕过错误

时间:2016-04-29 02:54:32

标签: r

我有一个214列长且多行长的数据帧,我想使用4列的值对每行进行一次Fisher精确测试。

我的数据框中的相关信息的示例子集如下:

Variant    DB.count.1    DB.count.2    pop.count.1    pop.count.2
A          23            62            35             70
B          81            4             39             22
C          51            42            49             52
D          NA            NA            65             8
E          73            21            50             33
F          72            13            81             10
G          61            32            75             21
H          NA            NA            42             22
I          NA            NA            60             20
J          80            12            72             24

我正在尝试使用for循环:

  1. 为Fisher的精确测试为每一行创建一个列联表,以便将DB.counts与pop.counts进行比较
  2. 使用此列联表运行Fisher精确测试以确定DB.counts和pop.counts之间是否存在差异
  3. 将p值结果输出到我的数据框
  4. 上的新列

    正如你所看到的,有" NA"某些位置的值,因此在某些列联表中,显然这会导致错误,这是可以的,但我希望代码在遇到此错误时输出一个值,例如"。&# 34;或"错误"并跳到下一行/列联表。

    即。我想要一个看起来像这样的输出:

    Variant    DB.count.1    DB.count.2    pop.count.1    pop.count.2    fishers
    A          23            62            35             70             0.4286
    B          81            4             39             22             <0.0001
    C          51            42            49             52             0.3921
    D          NA            NA            65             8              error
    E          73            21            50             33             0.0143
    F          72            13            81             10             0.5032
    G          61            32            75             21             0.0744
    H          NA            NA            42             22             error
    I          NA            NA            60             20             error
    J          80            12            72             24             0.0425
    

    我目前拥有的代码(基于R loop over Fisher test - Error message)是:

    df$fishers" <- for (i in 1:nrow(df))
    {
    table <- matrix(c(df[i,4], df[i,5], df[i,2], df[i,3]), ncol = 2, byrow = TRUE)
    fisher.test(table, alternative="greater")
    }
    

    这似乎按照我想要的方式创建了列联表,但是绕过错误并将p-vlaue打印到新列的问题仍然存在。我曾尝试使用try和tryCatch,但这样做并不成功。

    我是R初学者,所以非常感谢有关如何改进我的问题或任何有关我的问题的建议的任何建议!谢谢!

    编辑1:我现在尝试使用data.table包,如下所示,从数据集中得到了我需要的东西,没有&#34; NA&#34;值但是如何跳过错误并使代码继续?感谢!!!

    library(data.table)
    dt <- data.table(df)
    
    dt[, p.val := fisher.test(matrix(c(pop.count.1, pop.count.2, DB.count.1, DB.count.2), ncol=2), workspace=1e9)$p.value, by=Variant]
    
    df <- as.data.frame(dt)
    

1 个答案:

答案 0 :(得分:1)

您可以在循环中包含if-else语句,如下所示:

res <- NULL
for (i in 1:nrow(df)){
  table <- matrix(c(df[i,4], df[i,5], df[i,2], df[i,3]), ncol = 2, byrow = TRUE)
# if any NA occurs in your table save an error in p else run the fisher test
  if(any(is.na(table))) p <- "error" else p <- fisher.test(table, alternative="greater")$p.value
  # save all p values in a vector
  res <- c(res,p)
}
df$fishers <- res

或者将代码放在函数中并使用apply而不是循环:

foo <- function(y){
  # include here as.numeric to be sure that your values are numeric:
  table <-  matrix(as.numeric(c(y[4], y[5], y[2], y[3])), ncol = 2, byrow = TRUE)
  if(any(is.na(table))) p <- "error" else p <- fisher.test(table, alternative="greater")$p.value
  p
} 
df$fishers <- apply(df, 1, foo)