R:在大型数据帧中的多行上迭代 fisher 的测试以逐行获取输出
R: Iterate fisher’s test over multiple rows in large dataframe to get output row-by-row
我有一个包含多个分类值的大型数据集,这些值在两个不同的组中具有不同的整数值(计数)。
举个例子
Element <- c("zinc", "calcium", "magnesium", "sodium", "carbon", "nitrogen")
no_A <- c(45, 143, 10, 35, 70, 40)
no_B <- c(10, 11, 1, 4, 40, 30)
elements_df <- data.frame(Element, no_A, no_B)
Element
no_A
no_B
Zinc
45
10
Calcium
143
11
Magnesium
10
1
Sodium
35
4
Carbon
70
40
Nitrogen
40
30
之前我一直在使用下面的代码并手动更改 x 来获取输出值:
x = "calcium"
n1 = (elements_df %>% filter(Element== x))$no_A
n2 = sum(elements_df$no_A) - n1
n3 = (elements_df %>% filter(Element== x))$no_B
n4 = sum(elements_df$no_B) - n3
fisher.test(matrix(c(n1, n2, n3, n4), nrow = 2, ncol = 2, byrow = TRUE))
但我有一个包含 4000 行的非常大的数据集,我想要最有效的方法来遍历所有这些数据并查看哪些具有显着的 p 值。
我想我需要一个 for 循环和函数,虽然我已经查看了几个以前的类似问题(none 我觉得我可以使用)并且似乎使用 apply 可能是方式去。
所以,简而言之,谁能帮我编写代码,在每一行中迭代 x 并打印出每个元素对应的 p 值和优势比?
您可以像这样将它们全部放在一个漂亮的数据框中:
`row.names<-`(do.call(rbind, lapply(seq(nrow(elements_df)), function(i) {
f <- fisher.test(matrix(c(elements_df$no_A[i], sum(elements_df$no_A[-i]),
elements_df$no_B[i], sum(elements_df$no_B[-i])), nrow = 2));
data.frame(Element = elements_df$Element[i],
"odds ratio" = f$estimate, "p value" = scales::pvalue(f$p.value),
"Lower CI" = f$conf.int[1], "Upper CI" = f$conf.int[2],
check.names = FALSE)
})), NULL)
#> Element odds ratio p value Lower CI Upper CI
#> 1 zinc 1.2978966 0.601 0.6122734 3.0112485
#> 2 calcium 5.5065701 <0.001 2.7976646 11.8679909
#> 3 magnesium 2.8479528 0.469 0.3961312 125.0342574
#> 4 sodium 2.6090482 0.070 0.8983185 10.3719176
#> 5 carbon 0.3599468 <0.001 0.2158107 0.6016808
#> 6 nitrogen 0.2914476 <0.001 0.1634988 0.5218564
我有一个包含多个分类值的大型数据集,这些值在两个不同的组中具有不同的整数值(计数)。
举个例子
Element <- c("zinc", "calcium", "magnesium", "sodium", "carbon", "nitrogen")
no_A <- c(45, 143, 10, 35, 70, 40)
no_B <- c(10, 11, 1, 4, 40, 30)
elements_df <- data.frame(Element, no_A, no_B)
Element | no_A | no_B |
---|---|---|
Zinc | 45 | 10 |
Calcium | 143 | 11 |
Magnesium | 10 | 1 |
Sodium | 35 | 4 |
Carbon | 70 | 40 |
Nitrogen | 40 | 30 |
之前我一直在使用下面的代码并手动更改 x 来获取输出值:
x = "calcium"
n1 = (elements_df %>% filter(Element== x))$no_A
n2 = sum(elements_df$no_A) - n1
n3 = (elements_df %>% filter(Element== x))$no_B
n4 = sum(elements_df$no_B) - n3
fisher.test(matrix(c(n1, n2, n3, n4), nrow = 2, ncol = 2, byrow = TRUE))
但我有一个包含 4000 行的非常大的数据集,我想要最有效的方法来遍历所有这些数据并查看哪些具有显着的 p 值。
我想我需要一个 for 循环和函数,虽然我已经查看了几个以前的类似问题(none 我觉得我可以使用)并且似乎使用 apply 可能是方式去。
所以,简而言之,谁能帮我编写代码,在每一行中迭代 x 并打印出每个元素对应的 p 值和优势比?
您可以像这样将它们全部放在一个漂亮的数据框中:
`row.names<-`(do.call(rbind, lapply(seq(nrow(elements_df)), function(i) {
f <- fisher.test(matrix(c(elements_df$no_A[i], sum(elements_df$no_A[-i]),
elements_df$no_B[i], sum(elements_df$no_B[-i])), nrow = 2));
data.frame(Element = elements_df$Element[i],
"odds ratio" = f$estimate, "p value" = scales::pvalue(f$p.value),
"Lower CI" = f$conf.int[1], "Upper CI" = f$conf.int[2],
check.names = FALSE)
})), NULL)
#> Element odds ratio p value Lower CI Upper CI
#> 1 zinc 1.2978966 0.601 0.6122734 3.0112485
#> 2 calcium 5.5065701 <0.001 2.7976646 11.8679909
#> 3 magnesium 2.8479528 0.469 0.3961312 125.0342574
#> 4 sodium 2.6090482 0.070 0.8983185 10.3719176
#> 5 carbon 0.3599468 <0.001 0.2158107 0.6016808
#> 6 nitrogen 0.2914476 <0.001 0.1634988 0.5218564