2012-07-24 12 views
5

Sto cercando di capire come analizzare più risposte selezionate/multiple (ad esempio, "seleziona tutte le domande") in un sondaggio che ho recentemente condotto.Come utilizzare R per più domande selezionate?

SPSS ha funzionalità utili per analizzare i dati dei sondaggi online e questi tipi di domande, quindi suppongo che R abbia questo e altro. Trattare con queste risposte al sondaggio è un po 'complicato in Excel. Ad esempio, mostrami un istogramma/distribuzione a tutti quelli che amano il gelato alla fragola e al cioccolato per età.

Come si struttura il set di dati e quali sarebbero i comandi per eseguire alcune tabulazioni di base di frequenza, pareto e funzioni AND OR logiche?

+0

Per chiunque si sia imbattuto in questo ora: ora c'è un pacchetto dedicato per questo, MCRV: https://journal.r-project.org/archive/2014-1/koziol-bilder.pdf (commento di @matherion) – Moritz

risposta

5

Non ho trovato nulla che sia abbastanza conveniente come gli insiemi di risposte multiple in SPSS. Tuttavia, è possibile creare gruppi relativamente facilmente in base a nomi di colonne comuni e quindi utilizzare una qualsiasi delle funzioni o degli amici di apply() per scorrere tutti i gruppi. Ecco un approccio utilizzando adply() dal pacchetto plyr:

library(plyr) 
set.seed(1) 
#Fake data with three "like" questions. 0 = non selected, 1 = selected 
dat <- data.frame(resp = 1:10, 
        like1 = sample(0:1, 10, TRUE), 
        like2 = sample(0:1, 10, TRUE), 
        like3 = sample(0:1, 10, TRUE) 
       ) 

adply(dat[grepl("like", colnames(dat))], 2, function(x) 
    data.frame(Count = as.data.frame(table(x))[2,2], 
     Perc = as.data.frame(prop.table(table(x)))[2,2])) 
#----- 
    X1 Count Perc 
1 like1  6 0.6 
2 like2  5 0.5 
3 like3  3 0.3 
+0

almeno in termini di output, questo sembra essere solo come 'colSums (dat [-1])', e 'Perc' solo' Count/nrows (dat) '. C'è qualcosa di più "stravagante" che mi manca qui? - Interesse sinceramente perché anch'io devo occuparmi di questo tipo di domande, nel qual caso, di solito sono meno interessato a dividere per il numero di rispondenti, ma per il numero di risposte (con questa risposta, 14, (' sum (dat [-1]) ')). – A5C1D2H2I1M1N2O1R2T1

+0

@mrdwab - per una tabella dritta, probabilmente hai ragione. 'table()' ti permetterà facilmente di calcolare cross tabs anche usando lo stesso framework e non riesco facilmente a capire come si possa * adottare facilmente 'colSums()' per gestire quel caso, ovvero l'insieme di domande sopra per genere. – Chase

+0

Bello. Ho installato plyr con il Gestore pacchetti in OSX. Mi piace che questa soluzione catturi tutte le risposte prefissate "Q4". Nelle risposte, ho "1" per non selezionato e "2" per il controllo. In qualche modo questa soluzione ha contato automaticamente 2 secondi come controllati nonostante tu abbia usato 0/1. Come lo sa? – JHo

2

Recentemente ho scritto una funzione rapida a che fare con questi. Puoi facilmente modificarlo per aggiungere anche la proporzione delle risposte totali.

set.seed(1) 
dat <- data.frame(resp = 1:10, 
        like1 = sample(0:1, 10, TRUE), 
        like2 = sample(0:1, 10, TRUE), 
        like3 = sample(0:1, 10, TRUE)) 

La funzione:

multi.freq.table = function(data, sep="", dropzero=FALSE, clean=TRUE) { 
    # Takes boolean multiple-response data and tabulates it according 
    # to the possible combinations of each variable. 
    # 
    # See: http://stackoverflow.com/q/11348391/1270695 

    counts = data.frame(table(data)) 
    N = ncol(counts) 
    counts$Combn = apply(counts[-N] == 1, 1, 
         function(x) paste(names(counts[-N])[x], 
             collapse=sep)) 
    if (isTRUE(dropzero)) { 
    counts = counts[counts$Freq != 0, ] 
    } else if (!isTRUE(dropzero)) { 
    counts = counts 
    } 
    if (isTRUE(clean)) { 
    counts = data.frame(Combn = counts$Combn, Freq = counts$Freq) 
    } 
    counts 
} 

applicare la funzione:

multi.freq.table(dat[-1], sep="-") 
#    Combn Freq 
# 1      1 
# 2    like1 2 
# 3    like2 2 
# 4  like1-like2 2 
# 5    like3 1 
# 6  like1-like3 1 
# 7  like2-like3 0 
# 8 like1-like2-like3 1 

Spero che questo aiuti! Altrimenti, mostra alcuni esempi dell'output desiderato o descrivi alcune funzionalità, e vedrò cosa può essere aggiunto.

Aggiornamento

Dopo aver esaminato l'output di SPSS per questa linea, sembra che il seguente dovrebbe farlo per voi. Questo è abbastanza facile da avvolgere in una funzione se devi usarla molto.

data.frame(Freq = colSums(dat[-1]), 
      Pct.of.Resp = (colSums(dat[-1])/sum(dat[-1]))*100, 
      Pct.of.Cases = (colSums(dat[-1])/nrow(dat[-1]))*100) 
#  Freq Pct.of.Resp Pct.of.Cases 
# like1 6 42.85714   60 
# like2 5 35.71429   50 
# like3 3 21.42857   30 
+0

Grazie per aver trovato il tempo di rispondere a questo. Questa soluzione funziona. Ho dovuto fare un paio di passaggi extra che sono stati un buon esercizio di apprendimento. Subsetting del set di dati per Q4 (ad es., Dat1 <- dat [c (4:15)]). E convertendo la notazione nocheck (1)/check (2) a 0/1. È stato un buon esercizio di apprendimento per provare la soluzione. Grazie. – JHo

2
multfreqtable(data_set, "Banner") 
multfreqtable = function(data, question.prefix) { 
    z = length(question.prefix) 
    temp = vector("list", z) 

    for (i in 1:z) { 
    a = grep(question.prefix[i], names(data)) 
    b = sum(data[, a] != 0) 
    d = colSums(data[, a] != 0) 
    e = sum(rowSums(data[,a]) !=0) 
    f = as.numeric(c(d, b)) 
    temp[[i]] = data.frame(question = c(sub(question.prefix[i], 
              "", names(d)), "Total"), 
          freq = f, 
          percent_response = (f/b)*100, 
          percent_cases = (f/e)*100) 
    names(temp)[i] = question.prefix[i] 
    } 
    temp 
} 

fa un ottimo lavoro di dare i numeri, percentuali il numero di livello di casi e la percentuale al numero di livello di risposte. Perfetto per l'analisi di domande a risposta multipla

Problemi correlati