user3631848
user3631848

Reputation: 483

R Fisher's exact calculation

Here is the table format. Each row contains the information for contingency 2X2 table. I would like to calculate the odds ratio and corresponding p-value by fisher's exact test. After that, the odds ratio and p-value need to be added as another column in the table.

The input table looks like this :

A  B  C   D
1  1  10  77
2  6  9   72

For example :

A|C
---
B|D   

equal to

1|10
----
1|77

The output table should be something like :

A  B  C   D   OR    95CI   Pvalue
1  1  10  77  7.39  0.09;608.46  0.23
2  6  9   72  2.62  0.23;17.97   0.26

Upvotes: 0

Views: 428

Answers (2)

Martin Schmelzer
Martin Schmelzer

Reputation: 23889

Well play around with this: create new columns and get the number of rows in order to apply function(x) on every row.

df <- data.frame(A = 1:2, B=c(1,6), C=c(10,9), D=c(77,72))

df$OR     <- NA
df$`95CI` <- NA
df$Palue  <- NA
N <- nrow(df)

sapply(1:N, function(x) {
  tmp <- fisher.test(matrix(unlist(df[x, 1:4]), nrow=2, ncol=2, byrow=T))
  df[x,5:7] <<- c(round(tmp$estimate, 2), paste(round(tmp$conf.int,2), collapse = ";"),  round(tmp$p.value, 2))
})



> df
  A B  C  D   OR        95CI Palue
1 1 1 10 77 7.39 0.09;608.46  0.23
2 2 6  9 72 2.63  0.23;17.97  0.26

Upvotes: 1

zx8754
zx8754

Reputation: 56149

Loop through rows, convert to matrix, pass it to fisher, then prettify output:

cbind(df1,
      do.call(rbind,
              apply(df1, 1, function(i) {
                ft <- fisher.test(matrix(i, nrow = 2, ncol = 2))
                cbind.data.frame(
                  OR = round(ft$estimate, 2),
                  CI95 = paste(round(ft$conf[1], 2),
                               round(ft$conf[2], 2), sep = ";"),
                  Pvalue = ft$p.value)

              }))
      )

#             A B  C  D   OR        CI95    Pvalue
# odds ratio  1 1 10 77 7.39 0.09;608.46 0.2331461
# odds ratio1 2 6  9 72 2.63  0.23;17.97 0.2565293

Upvotes: 1

Related Questions