我有一个大型数据框,其中行作为物种,从 2 年开始计数作为列。我想为每一行创建一个列联表,以测试从第一年到第二年是否有重大变化(减少)。这是类似的假装数据:
Species 2016 2017
cat 14 8
dog 16 12
bird 10 5
然后对于每一行我想要一个像这样的表格:
cat 2017 2018
present 14 8
absent 0 6
dog 2017 2018
present 16 12
absent 0 4
bird 2017 2018
present 10 5
absent 0 5
这样,我将对每个表进行费舍尔精确检验,以测试下降是否显着。
我认为这可以通过 dplyr 来完成,或者应用类似于下面链接的行循环,但我不确定如何首先构建正确的表列表。 How to convert data frame to contingency table in R?
我一次从一行开始:
A <- df[1,1:3]
A[2,] <- 0
A[2,3] <- (A[1,2] - A[1,3])
fisher.test(A[2:3])
有关如何将其应用于大量行的建议将不胜感激!我的大脑在编码方面真的很困难。
最佳答案
一种tidyverse
可能性可能是:
library(tidyverse)
library(broom)
df %>%
rowid_to_column() %>%
gather(var, present, -c(Species, rowid)) %>%
arrange(rowid, var) %>%
group_by(rowid) %>%
mutate(absent = lag(present, default = first(present)) - present) %>%
ungroup() %>%
select(-rowid, -var) %>%
nest(present, absent) %>%
mutate(p_value = data %>%
map(~fisher.test(.)) %>%
map(tidy) %>%
map_dbl(pluck, "p.value")) %>%
select(-data)
Species p_value
<chr> <dbl>
1 cat 0.0159
2 dog 0.101
3 bird 0.0325
在这里,它首先执行从宽到长的数据转换,不包括“Species”列和引用行 ID 的列。其次,它根据行 ID 和原始列名称(按行 ID 引用年份和组)排列数据。第三,它计算年份之间的差异。最后,它嵌套每个物种的当前和不存在变量并执行fisher.test
,然后返回每个物种的 p 值。
关于r - 如何为数据框的每一行创建列联表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55427470/