2

親愛なるプログラミングの神様へ

R で一連のカイ 2 乗検定 (私の種の存在/不在 data.frame の列ごとに 1 つの検定) を実行したいと思います。種 (列名)、カイ 2 乗検定統計量、df、および p.value を出力します。

私の種のデータ スニペット (実際のサイズ = 50x131):

   Species<-structure(list(Acesac = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 1L
), Allpet = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L), Ambser = c(0L, 
0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L), Anoatt = c(0L, 0L, 0L, 1L, 0L, 
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 
0L, 1L, 1L, 1L), Aritri = c(0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 
0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L
)), .Names = c("Acesac", "Allpet", "Ambser", "Anoatt", "Aritri"
), row.names = c("BS1", "BS10", "BS2", "BS3", "BS4", "BS5", "BS6", 
"BS7", "BS8", "BS9", "LC1", "LC10", "LC2", "LC3", "LC4", "LC5", 
"LC6", "LC7", "LC8", "LC9", "TR1", "TR10", "TR2", "TR3", "TR4"
), class = "data.frame")

My environmental data snippet:
Env<-structure(list(Rock = structure(1:25, .Label = c("BS1", "BS10", 
"BS2", "BS3", "BS4", "BS5", "BS6", "BS7", "BS8", "BS9", "LC1", 
"LC10", "LC2", "LC3", "LC4", "LC5", "LC6", "LC7", "LC8", "LC9", 
"TR1", "TR10", "TR2", "TR3", "TR4", "TR5", "TR6", "TR7", "TR8", 
"TR9", "WD1", "WD10", "WD2", "WD3", "WD4", "WD5", "WD6", "WD7", 
"WD8", "WD9", "WW1", "WW10", "WW2", "WW3", "WW4", "WW5", "WW6", 
"WW7", "WW8", "WW9"), class = "factor"), Climbed = structure(c(1L, 
2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 1L, 2L, 2L, 1L, 2L), .Label = c("climbed", "unclimbed"
), class = "factor")), .Names = c("Rock", "Climbed"), row.names = c(NA, 
25L), class = "data.frame")

次の適用関数コードは、登った岩と登っていない岩 (Env$Climbed) での特定の種の出現回数を含む分割表を最初に作成することにより、種 (列) ごとにカイ 2 乗検定を実行します。

apply(Species, 2, function(x) {
  Table<-table(Env$Climbed, x)
  Test<-chisq.test(Table, corr = TRUE)
  out <- data.frame("Chi.Square" = round(Test$statistic,3)
                  , "df" = Test$parameter
                  , "p.value" = round(Test$p.value, 3)
  )
  }) 

これにより、種 (列) ごとに個別の data.frame が生成されます。各種の列名も含む 1 つの data.frame を作成したいと思います。このようなもの:

mydf<-data.frame("spp"= colnames(Species[1:25,]), "Chi.sq"=c(1:25), "df"=
  c(1:25),"p.value"= c(1:25))

これは ddply または adply で行うべきですか? それともただのループ?(私は試しましたが、失敗しました)。同様のトピックに関する投稿を確認しました ([ R で for ループを使用したカイ 2 乗分析) が、私の目的のために機能させることができませんでした。

あなたの時間と専門知識をありがとう!TC

4

3 に答える 3

1

あなたも試すことができます

kk <- apply(Species,2,....) 
library(plyr)
ldply(kk,.id='spp') 
 spp Chi.Square df p.value
1 Acesac      0.000  1   1.000
2 Allpet      0.000  1   1.000
3 Ambser      0.000  1   1.000
4 Anoatt      0.338  1   0.561
5 Aritri      0.085  1   0.770

更新:

library(plyr)
library(reshape2)
ddply(setNames(melt(Species), c("spp", "value")), .(spp), function(x) {
Test <- chisq.test(table(Env$Climbed, x$value), corr = TRUE)
data.frame(Chi.Square = round(Test$statistic, 3), df = Test$parameter, p.value = round(Test$p.value, 
    3))

}))

于 2014-06-12T02:09:19.540 に答える
1

applyで使用しないでくださいdata.frames。これは、一部のデータ構造 (つまり、因子) に対して意図しない結果をもたらす可能性があるマトリックスに内部的に強制します。また、効率的でもありません(メモリに関して)。

列ごとに関数を適用する場合は、lapply(data.frameがリストであるため)を使用します

plyr::ldplyリストではないものを自動的に返す doを使用できますdata.frame

# rewrite the function so `Env$Climbed` is not hard coded....
my_fun <- function(x,y) {
  Table<-table(y, x)
  Test<-chisq.test(Table, corr = TRUE)
  out <- data.frame("Chi.Square" = round(Test$statistic,3)
                    , "df" = Test$parameter
                    , "p.value" = round(Test$p.value, 3)
  )

}
library(plyr)
results <- ldply(Species,my_fun, y = Env$Climbed)
results
# .id Chi.Square df p.value
# 1 Acesac      0.000  1   1.000
# 2 Allpet      0.000  1   1.000
# 3 Ambser      0.000  1   1.000
# 4 Anoatt      0.338  1   0.561
# 5 Aritri      0.085  1   0.770
于 2014-06-12T03:44:25.553 に答える