FcmC
FcmC

Reputation: 143

Referencing elements in for loop r

I am trying to iteratively run some prop.tests on a dataframe using for loop. However I don't seem to be to call the elements in the loop inside the brackets. Here is my code:

head(fact_DIAG)
  Studio INC2_A INC2_B INC2_F INC2_G INC2_H INC2_I FemaleGend INP AGE_DEP HIS_TS NBTS
1      0      1      1      1      0      1      1          1   0       5      1    3
2      0      1      1      1      1      0      0          1   1       4      0    1
3      0      1      1      1      1      1      0          0   0       5      1    3
4      0      1      1      1      1      1      1          1   0       3      0    1
5      0      1      1      1      1      1      1          1   0       4      1    2
6      0      1      1      1      1      1      1          1   0       5      1    3
  NBMOOD_Y PSYHOSP MH_F1 DUR_DEP AD_1 AD_2 AD_3 AD_4 DS_1 DS_2 DS_3 DS_5 DS_6 DS_7 DS_8
1        2       3     0       3    0    0    0    0    0    0    0    0    0    0    0
2        2       1     0       4    0    1    1    1    0    0    0    1    0    0    1
3        3       2     0       3    0    0    0    1    1    0    0    1    0    0    0
4        3       3     0       3    0    0    1    0    0    0    0    0    0    0    1
5        2       3     0       3    0    0    1    0    0    0    0    0    1    1    0
6        3       3     0       3    0    1    1    1    0    0    0    1    1    0    0
  DS_9 DS_10 DS_11 ALC SUBST PAN OBS PHO GAD EAT_1 EAT_2 BorderPersonality ADHD ANX_BZD
1    0     1     0   0     0   0   0   1   0     0     0                 0    0       0
2    0     1     1   0     0   0   0   0   0     0     0                 0    0       0
3    0     0     0   0     0   0   0   0   0     0     0                 0    0       1
4    0     0     0   0     0   0   0   0   0     0     0                 0    0       1
5    0     0     0   0     0   0   0   0   0     0     0                 0    0       1
6    0     1     1   0     0   0   0   0   0     0     0                 0    0       0
  ANX_OTH ANX_TT AD_SSRI AD_SNRI AD_TCA AD_TT motor3 MAR Inpatient     DIAG
1       0      0       1       0      1     1      0   1         0 unipolar
2       0      0       0       1      0     1      0   1         0 unipolar
3       0      1       1       0      1     1      0   1         0 unipolar
4       0      1       1       0      0     1      0   2         0 unipolar
5       0      1       1       0      1     1      2   1         0 unipolar
6       0      0       1       0      0     1      0   1         0 unipolar

col<-names(fact_DIAG)[!names(fact_DIAG)%in%c("DIAG","Studio")]

list_chi<-vector("list")

fact_DIAG<-as.data.frame(fact_DIAG)

for(i in col) {
        list_chi[[i]]<-broom::tidy(prop.test(table(fact_DIAG$DIAG, fact_DIAG[, i])))
}

chi<-bind_rows(list_chi, .id = 'Var')

The for loop throws this error: Error in prop.test() : 'x' must have 2 columns

As if I was not calling the first element of the table() function. If I reverse the order inside table() function, the code works.

for(i in col) {
        list_chi[[i]]<-broom::tidy(prop.test(table(fact_DIAG[, i]), fact_DIAG$DIAG))
}

How can I keep the order of elements called in table() while making the loop work? Thanks.

dput(head(fact_DIAG[c(1:6, ncol(fact_DIAG))], 20))
structure(list(Studio = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("0", 
"1"), class = "factor"), INC2_A = structure(c(2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L
), .Label = c("0", "1"), class = "factor"), INC2_B = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), INC2_F = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 2L, 2L), .Label = c("0", "1"), class = "factor"), INC2_G = structure(c(1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), INC2_H = structure(c(2L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 2L, 2L), .Label = c("0", "1"), class = "factor"), DIAG = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), .Label = c("unipolar", "bipolar"), class = "factor")), row.names = c(NA, 
20L), class = "data.frame")

Upvotes: 0

Views: 90

Answers (1)

Rui Barradas
Rui Barradas

Reputation: 76450

See if the following code solves the problem. It creates a list_chi before the for loop and in the loop calls prop.test with tryCatch wrapped around it, in order to catch eventual errors. In the end it creates a tibble result with just the tests results that worked.

col <- names(fact_DIAG)[!names(fact_DIAG) %in% c("DIAG","Studio")]
list_chi <- vector("list", length = length(col))
names(list_chi) <- col

for(i in col) {
  tbl <- table(fact_DIAG[c(i, "DIAG")])
  n <- colSums(tbl)
  list_chi[[i]] <- tryCatch(broom::tidy(prop.test(tbl, n)),
                            error = function(e) e)
}

ok <- !sapply(list_chi, inherits, "error")
result <- do.call(rbind, list_chi[ok])

Upvotes: 1

Related Questions