在 R 中使用 for 循环进行卡方分析

发布于 2024-12-04 05:11:47 字数 1231 浏览 1 评论 0原文

我正在尝试对数据中变量的所有组合进行卡方分析,我的代码是:

Data <- esoph[ , 1:3]
OldStatistic <- NA
for(i in 1:(ncol(Data)-1)){
for(j in (i+1):ncol(Data)){
Statistic <- data.frame("Row"=colnames(Data)[i], "Column"=colnames(Data)[j],
                     "Chi.Square"=round(chisq.test(Data[ ,i], Data[ ,j])$statistic, 3),
                     "df"=chisq.test(Data[ ,i], Data[ ,j])$parameter,
                     "p.value"=round(chisq.test(Data[ ,i], Data[ ,j])$p.value, 3),
                      row.names=NULL)
temp <- rbind(OldStatistic, Statistic)
OldStatistic <- Statistic
Statistic <- temp
}
}

str(Data)
'data.frame':   88 obs. of  3 variables:
 $ agegp: Ord.factor w/ 6 levels "25-34"<"35-44"<..: 1 1 1 1 1 1 1 1 1 1 ...
 $ alcgp: Ord.factor w/ 4 levels "0-39g/day"<"40-79"<..: 1 1 1 1 2 2 2 2 3 3 ...
 $ tobgp: Ord.factor w/ 4 levels "0-9g/day"<"10-19"<..: 1 2 3 4 1 2 3 4 1 2 ...


Statistic
    Row Column Chi.Square df p.value
1 agegp  tobgp      2.400 15       1
2 alcgp  tobgp      0.619  9       1

我的代码给出了变量 1 与变量 3、变量 2 与变量 3 的卡方分析输出,并且变量 1 缺失vs 变量2。我努力尝试但无法修复代码。任何意见和建议都将受到高度赞赏。我想对所有可能的组合进行交叉制表。提前致谢。

编辑

我曾经在 SPSS 中进行此类分析,但现在我想切换到 R。

I'm trying to do chi square analysis for all combinations of variables in the data and my code is:

Data <- esoph[ , 1:3]
OldStatistic <- NA
for(i in 1:(ncol(Data)-1)){
for(j in (i+1):ncol(Data)){
Statistic <- data.frame("Row"=colnames(Data)[i], "Column"=colnames(Data)[j],
                     "Chi.Square"=round(chisq.test(Data[ ,i], Data[ ,j])$statistic, 3),
                     "df"=chisq.test(Data[ ,i], Data[ ,j])$parameter,
                     "p.value"=round(chisq.test(Data[ ,i], Data[ ,j])$p.value, 3),
                      row.names=NULL)
temp <- rbind(OldStatistic, Statistic)
OldStatistic <- Statistic
Statistic <- temp
}
}

str(Data)
'data.frame':   88 obs. of  3 variables:
 $ agegp: Ord.factor w/ 6 levels "25-34"<"35-44"<..: 1 1 1 1 1 1 1 1 1 1 ...
 $ alcgp: Ord.factor w/ 4 levels "0-39g/day"<"40-79"<..: 1 1 1 1 2 2 2 2 3 3 ...
 $ tobgp: Ord.factor w/ 4 levels "0-9g/day"<"10-19"<..: 1 2 3 4 1 2 3 4 1 2 ...


Statistic
    Row Column Chi.Square df p.value
1 agegp  tobgp      2.400 15       1
2 alcgp  tobgp      0.619  9       1

My code gives my the chi square analysis output for variable 1 vs variable 3, and variable 2 vs variable 3 and is missing for variable 1 vs variable 2. I tried hard but could not fixed the code. Any comment and suggestion will be highly appreciated. I'd like like to do cross tabulation for all possible combinations. Thanks in advance.

EDIT

I used to do this kind of analysis in SPSS but now I want to switch to R.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听你说爱我 2024-12-11 05:11:47

如果您提供数据样本,我们将不胜感激,但我认为这对您有用。首先,使用 combn 创建所有列的组合。然后编写一个与 apply 函数一起使用的函数来迭代组合。我喜欢使用 plyr 因为它很容易指定您想要的后端数据结构。另请注意,您只需为每个列组合计算一次卡方检验,这也会大大加快速度。

library(plyr)

combos <- combn(ncol(Dat),2)

adply(combos, 2, function(x) {
  test <- chisq.test(Dat[, x[1]], Dat[, x[2]])

  out <- data.frame("Row" = colnames(Dat)[x[1]]
                    , "Column" = colnames(Dat[x[2]])
                    , "Chi.Square" = round(test$statistic,3)
                    ,  "df"= test$parameter
                    ,  "p.value" = round(test$p.value, 3)
                    )
  return(out)

})  

A sample of your data would be appreciated, but I think this will work for you. First, create a combination of all columns with combn. Then write a function to use with an apply function to iterate through the combos. I like to use plyr since it is easy to specify what you want for a data structure on the back end. Also note you only need to compute the chi square test once for each combination of columns, which should speed things up quite a bit as well.

library(plyr)

combos <- combn(ncol(Dat),2)

adply(combos, 2, function(x) {
  test <- chisq.test(Dat[, x[1]], Dat[, x[2]])

  out <- data.frame("Row" = colnames(Dat)[x[1]]
                    , "Column" = colnames(Dat[x[2]])
                    , "Chi.Square" = round(test$statistic,3)
                    ,  "df"= test$parameter
                    ,  "p.value" = round(test$p.value, 3)
                    )
  return(out)

})  
情域 2024-12-11 05:11:47

我写了我自己的函数。它创建一个矩阵,其中所有名义变量都相互测试。它还可以将结果保存为 Excel 文件。它显示所有小于 5% 的 p 值。

funMassChi <- function (x,delFirst=0,xlsxpath=FALSE) {
  options(scipen = 999)

  start <- (delFirst+1)
  ds <- x[,start:ncol(x)]

  cATeND <- ncol(ds)
  catID  <- 1:cATeND

  resMat <- ds[1:cATeND,1:(cATeND-1)]
  resMat[,] <- NA

    for(nCc in 1:(length(catID)-1)){
      for(nDc in (nCc+1):length(catID)){
        tryCatch({
          chiRes <- chisq.test(ds[,catID[nCc]],ds[,catID[nDc]])
          resMat[nDc,nCc]<- chiRes[[3]]
        }, error=function(e){cat(paste("ERROR :","at",nCc,nDc, sep=" "),conditionMessage(e), "\n")})
      }
    }
  resMat[resMat > 0.05] <- "" 
  Ergebnis <- cbind(CatNames=names(ds),resMat)
  Ergebnis <<- Ergebnis[-1,] 

  if (!(xlsxpath==FALSE)) {
     write.xlsx(x = Ergebnis, file = paste(xlsxpath,"ALLChi-",Sys.Date(),".xlsx",sep=""),
             sheetName = "Tabelle1", row.names = FALSE)
  }
}

funMassChi(categorialDATA,delFirst=3,xlsxpath="C:/folder1/folder2/")

delFirst 可以删除前n 列。所以如果你有一个计数索引或者你不想测试的东西。

我希望这可以帮助其他人。

I wrote my own function. It creates a matrix where all nominal variables are tested against each other. It can also save the results as excel file. It displays all the pvalues that are smaller than 5%.

funMassChi <- function (x,delFirst=0,xlsxpath=FALSE) {
  options(scipen = 999)

  start <- (delFirst+1)
  ds <- x[,start:ncol(x)]

  cATeND <- ncol(ds)
  catID  <- 1:cATeND

  resMat <- ds[1:cATeND,1:(cATeND-1)]
  resMat[,] <- NA

    for(nCc in 1:(length(catID)-1)){
      for(nDc in (nCc+1):length(catID)){
        tryCatch({
          chiRes <- chisq.test(ds[,catID[nCc]],ds[,catID[nDc]])
          resMat[nDc,nCc]<- chiRes[[3]]
        }, error=function(e){cat(paste("ERROR :","at",nCc,nDc, sep=" "),conditionMessage(e), "\n")})
      }
    }
  resMat[resMat > 0.05] <- "" 
  Ergebnis <- cbind(CatNames=names(ds),resMat)
  Ergebnis <<- Ergebnis[-1,] 

  if (!(xlsxpath==FALSE)) {
     write.xlsx(x = Ergebnis, file = paste(xlsxpath,"ALLChi-",Sys.Date(),".xlsx",sep=""),
             sheetName = "Tabelle1", row.names = FALSE)
  }
}

funMassChi(categorialDATA,delFirst=3,xlsxpath="C:/folder1/folder2/")

delFirst can delete the first n columns. So if you have an count index or something you dont want to test.

I hope this can help anyone else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文