Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert data frame to contingency table in R?

I have a simple question. How to convert a data frame into a contingency table for Fisher's Exact Test?

I have data having about 19000 rows:

head(data)

          R_T1   R_T2    NR_T1  NR_T2
GMNN      14      60     70     157
GORASP2    7      67     39     188
TTC34      5      69     41     186
ZXDC       8      66     37     190
ASAH2      9      65     46     181

I would like to transform each row into a contingency table to perform Fisher's Exact Test. For example, for GMNN:

       R   NR
T1    14   70
T2    60  157

fisher.test(GMNN, alternative="two.sided")

Fisher's Exact Test for Count Data

data:  GMNN
p-value = 0.05273
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
0.2531445 1.0280271
sample estimates:
odds ratio 
0.5243787 

Since I have 19000 rows of data, I would prefer to output to be:

          R_T1   R_T2    NR_T1  NR_T2    p-value    odds_ratio
GMNN      14      60     70     157      0.05273    0.5243787 
GORASP2    7      67     39     188       0.1367     0.504643
TTC34      5      69     41     186      0.02422    0.3297116
ZXDC       8      66     37     190       0.3474    0.6233377
ASAH2      9      65     46     181       0.1648    0.5458072

I am lost on how to do this. Could someone help? Thanks!

like image 806
kin182 Avatar asked Jan 01 '26 10:01

kin182


2 Answers

You can convert each row into a contingency table with matrix:

ft.res <- apply(data, 1, function(x){
    t1 <- fisher.test(matrix(x, nrow = 2))
    data.frame(p_value = t1$p.value, odds_ratio = t1$estimate)
})

cbind(data, do.call(rbind, ft.res))
#         R_T1 R_T2 NR_T1 NR_T2    p_value odds_ratio
# GMNN      14   60    70   157 0.05273179  0.5243787
# GORASP2    7   67    39   188 0.13671487  0.5046430
# TTC34      5   69    41   186 0.02421765  0.3297116
# ZXDC       8   66    37   190 0.34744964  0.6233377
# ASAH2      9   65    46   181 0.16478480  0.5458072
like image 169
mt1022 Avatar answered Jan 03 '26 04:01

mt1022


You can do it using apply, looping through the rows of your dataframe:

## Replicating the data
d  = data.frame(R_T1=c(14,7,5,8,9),R_T2=c(60,67,69,66,65),NR_T1=c(70,39,41,37,46),NR_T2=c(157,188,186,190,181))
row.names(d) = c("GMNN","GORASP2","TTC34","ZXDC","ASAH2")
## Computing the fisher test and getting the values for each row 
d[,c("p_value","odds_ratio")] = t(apply(d,1,function(x) {f=fisher.test(matrix(x,2,2));c(f$p.value,f$estimate)}

        R_T1 R_T2 NR_T1 NR_T2    p_value odds_ratio
GMNN      14   60    70   157 0.05273179  0.5243787
GORASP2    7   67    39   188 0.13671487  0.5046430
TTC34      5   69    41   186 0.02421765  0.3297116
ZXDC       8   66    37   190 0.34744964  0.6233377
ASAH2      9   65    46   181 0.16478480  0.5458072
like image 36
Lamia Avatar answered Jan 03 '26 03:01

Lamia



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!