eine MENGE Partialkorrelationen

Alles zum Thema der beschreibenden Statistik

Moderator: jogo

Antworten
-R-atlos

eine MENGE Partialkorrelationen

Beitrag von -R-atlos »

Hallo zusammen,

ich habe eine dringende Frage. Um kurz den Ausgangszustand zu beschreiben:
es liegt ein Datensatz vor mit Daten von N=42 VPn.

Für jede VP wurden die Werte für sechs Konstrukte erhoben:
Lebenszufriedenheit, Selbstwirksamkeit, interne Kontrollüberzeugung, externe Kontrollüberzeugung, Optimismus, Pessimismus.
Über die Daten für diese sechs Dimensionen hinaus sind die Daten für 69 Ratings vorhanden.
Zusätzlich wurden noch das Geschlecht so wie das Alter für jede VP erhoben.

Ich möchte nun die Partialkorrelationen (inkl. p-Wert) für jedes Konstrukt korreliert mit jedem einzelnen Rating berechnen (also sechs mal 69 Korrelationen), kontrolliert für Geschlecht und Alter.

Das Berechnen funktioniert hervorragend mit der Funktion pcor aus dem Paket "ppcor".
Ich erstelle einfach einen Dataframe mit dem cbind-Befehl (z.B. lifesat.rating1.part = cbind(lifesat,rating1,age,sex))und führe dann die Funktion pcor aus (pcor(lifesat.rating1.part)). Partialkorrelation für lifesat mit rating1, kontrolliert für Alter und Geschlecht werden inkl. p-Wert ausgegeben. Allerdings ist dieses Vorgehen einfach sehr mühsam und dauert bei der Anzahl an Korrelationen die berechnet werden sollen verdammt lange.

Hat jemand evtl eine Idee, wie sich das Vorgehen beschleunigen ließe? Oder gibt es eine andere Funktion, mit der ich mir die Korrelationen einfacher geben lassen kann.

Oder auch: ich kenne mich mit SPSS nicht wirklich aus, hat jemand eine Ahnung ob man die Korrelationen damit schneller und einfacher berechnen kann?

Vielen Dank im Voraus und liebe Grüße,
-R-atlos
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: eine MENGE Partialkorrelationen

Beitrag von jogo »

Hallo -R-atlos,

willkommen im Forum. Kannst Du bitte den Quelltext bis zum ersten

Code: Alles auswählen

pcor(lifesat.rating1.part)
zeigen?
Bei dem Code lifesat.rating1.part = cbind(lifesat,rating1,age,sex) wundert mich, dass die Ratings einfach so in der Umgebung rumliegen sollen. Du hast doch 69 solche Ratings. Verwendest Du das böse attach() :?:

Gruß, Jörg
-R-atlos

Re: eine MENGE Partialkorrelationen

Beitrag von -R-atlos »

Hallo Jörg,

vielen Dank für deine Antwort.
Ich bin leider kein R-Experte, ich kenne mich nur rudimentär aus, ich werde aber versuchen so gut es geht zu antworten.

Doch, ich benutze tatsächlich die attach()-Funktion. Inwiefern ist das problematisch?

Ich habe den Datensatz (Excel-Datei) normal geladen, ihn "alldata2" benannt, alle Variablen (Konstrukte, Ratings, Age, Sex) sind in dem Datensatz enthalten. Dann habe ich die attach-Funktion verwendet (attach(alldata2)).

Hoffe, das hilft dir weiter.

Danke und viele Grüße
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: eine MENGE Partialkorrelationen

Beitrag von jogo »

Hallo -R-atlos,
-R-atlos hat geschrieben: So Aug 20, 2017 11:04 am Doch, ich benutze tatsächlich die attach()-Funktion. Inwiefern ist das problematisch?
Kurz gesagt: ein Anfänger kann die Folgen der Verwendung von attach() nicht abschätzen.
Mehr zum Thema: viewtopic.php?f=7&t=5
Zu attach() gibt es inzwischen ein Sprüchlein:

Code: Alles auswählen

library("fortunes")
fortune(379)
unabhängig davon gilt für attach() das Gleiche, was über assign() verlautet:

Code: Alles auswählen

fortune(236)
Ich habe den Datensatz (Excel-Datei) normal geladen, ihn "alldata2" benannt, alle Variablen (Konstrukte, Ratings, Age, Sex) sind in dem Datensatz enthalten. Dann habe ich die attach-Funktion verwendet (attach(alldata2)).
Ich hatte Dich gebeten, all den Code vom Einlesen bis zur ersten Verwendung von pcor(lifesat.rating1.part) zu posten. Diese Bitte erfolgte nicht, weil ich so erpicht darauf bin, fremde Quelltexte auszuspähen, sondern weil ich nur mit dieser Information Dir weiter helfen kann. Es bleibt natürlich Deine Entscheidung, ob Du den Code zeigen möchtest.
Allerdings werde ich Dir auch kaum helfen können, wenn ich nicht sehen kann, was Du dort wie programmiert hast.
Hoffe, das hilft dir weiter.
nicht so recht (siehe vorherigen Absatz)

Gruß, Jörg
-R-atlos

Re: eine MENGE Partialkorrelationen

Beitrag von -R-atlos »

Lieber Jörg,

ich danke dir für deine Antwort.
Der Grund, warum ich nicht den Quelltext gepostet habe, liegt auch nicht daran, dass ich ein Quelltext-Geier bin, der cheap ist und ungern Quelltexte rausrückt, sondern weil ich in der Zwischenzeit UNMENGEN an Berechnungen durchgeführt hatte, und den Quelltext nicht so einfach hier reinkopieren kann.
Ich habe jetzt eine neue Session gestartet, hier der Quelltext bis zu dem Teil, bis ich die pcor-Funktion anwende:

Code: Alles auswählen

R version 3.4.1 (2017-06-30) -- "Single Candle"
Copyright (C) 2017 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin15.6.0 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

During startup - Warning messages:
1: Setting LC_CTYPE failed, using "C" 
2: Setting LC_COLLATE failed, using "C" 
3: Setting LC_TIME failed, using "C" 
4: Setting LC_MESSAGES failed, using "C" 
5: Setting LC_MONETARY failed, using "C" 
[Workspace loaded from ~/.RData]

> library(readxl)
> alledaten <- read_excel("~/Desktop/Items & Ratings LG40_Cem_Aug 2017.xlsx", 
+     na = "NA")
> View(alledaten)
> library("Hmisc", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
Loading required package: lattice
Loading required package: survival
Loading required package: Formula
Loading required package: ggplot2

Attaching package: 'Hmisc'

The following objects are masked from 'package:base':

    format.pval, round.POSIXt, trunc.POSIXt, units

> library("ICC", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
> library("MASS", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
> library("psy", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
> library("psych", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")

Attaching package: 'psych'

The following object is masked from 'package:psy':

    wkappa

The following object is masked from 'package:Hmisc':

    describe

The following objects are masked from 'package:ggplot2':

    %+%, alpha

> library("ppcor", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
> attach(alledaten)
> swls.cue1.n.part = cbind(swls_ac_mw,cue_mw_1,age,sex)
> pcor(swls.cue1.n.part)
$estimate
            swls_ac_mw   cue_mw_1          age         sex
swls_ac_mw 1.000000000  0.3308206  0.003364578  0.28546076
cue_mw_1   0.330820647  1.0000000 -0.111093843 -0.16400741
age        0.003364578 -0.1110938  1.000000000  0.09064288
sex        0.285460760 -0.1640074  0.090642879  1.00000000

$p.value
           swls_ac_mw   cue_mw_1       age        sex
swls_ac_mw 0.00000000 0.04248745 0.9840052 0.08233963
cue_mw_1   0.04248745 0.00000000 0.5066828 0.32515479
age        0.98400521 0.50668276 0.0000000 0.58836215
sex        0.08233963 0.32515479 0.5883621 0.00000000

$statistic
           swls_ac_mw   cue_mw_1         age        sex
swls_ac_mw 0.00000000  2.1033562  0.02018758  1.7871262
cue_mw_1   2.10335620  0.0000000 -0.67071483 -0.9975522
age        0.02018758 -0.6707148  0.00000000  0.5461053
sex        1.78712617 -0.9975522  0.54610534  0.0000000

$n
[1] 40

$gp
[1] 2

$method
[1] "pearson"


Danke und Grüße
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: eine MENGE Partialkorrelationen

Beitrag von bigben »

Hallo,

und willkommen im Forum. Ich glaube nicht, dass ich Dein Ansinnen statistisch gut finde, aber hier geht es ja nicht um Statistik, sondern um R. Wenn ich das Problem richtig verstehe, dann ist es Dir zuviel Arbeit, die ganzen Korrelationen von Hand zusammen zu tippen. Die Gefahr, Fehler zu machen, wäre wohl auch zu groß.
Mein Vorschlag wäre, die einzelnen Datenreihen nicht über ihren Namen, sondern über ihre Spaltennummer anzusprechen. Im Allgemeinen ist das keine gute Idee, in diesem konkreten Fall könnte es genau die richtige Lösung sein. Ich habe da mal ein Beispiel fabriziert:

Code: Alles auswählen

beispieldaten <- data.frame(konstruktA = rnorm(42),
                           konstruktB = rnorm(42),
                           konstruktC = rnorm(42),
                           anderes = rnorm(42),
                           rating1 = rnorm(42),
                           rating2 = rnorm(42),
                           rating3 = rnorm(42),
                           rating4 = rnorm(42))

# die Konstrukte liegen in den Spalten 1 bis 3
kons <- 1:3

# die Ratings liegen in den Spalten 5:8
rati <- 5:8

# Alle Spaltenkombinationen erhalten wir so
kombis <- expand.grid(kons, rati)

# über die Kombis können wir jetzt iterieren
for(i in 1:nrow(kombis)){
    # erst ausgeben, was ich hier korrelliere
    print(paste0(names(beispieldaten[kombis[i,1]]), " vs ",
          paste0(names(beispieldaten[kombis[i,2]]))))
    # dann die Korrelation -oder was auch immer- berechnen und ausgeben.
    print(cor.test(beispieldaten[,kombis[i,1]],
                   beispieldaten[,kombis[i,2]]))
}
Ich habe mich für das Beispiel mit 3 Konstrukten und 4 Ratings begnügt und habe auch keine Partialkorrelationen sondern nur einfache Korrelationen berechnet. Das kannst Du bestimmt für Dich anpassen. Nachdem die Spaltennummer von Konstrukten und Ratings bekannt sind, kann man über die Funktion expand.grid alle Kombinationen daraus erstellen und über diese Kombinationen dann mit einer Schleife laufen.
Auf diese Weise braucht man dann auch gar kein attach, was sicher besser ist.

LG,
Bernhard

PS: viewtopic.php?f=20&t=29
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
-R-atlos

Re: eine MENGE Partialkorrelationen

Beitrag von -R-atlos »

Hallo Bernhard,

vielen lieben Dank für deine Antwort, das teste ich gleich mal aus.

Danke und Gruß
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: eine MENGE Partialkorrelationen

Beitrag von bigben »

Gut, dann will ich schnell noch was ergänzen: Wenn man das so macht, und die Daten über die Spaltennummer anspricht, dann muss nur irgendein Scherzkeks in Excel eine neue Reihe einfügen oder alles eine Reihe nach rechts kopieren, und schon führt dieses Vorgehen zu falschen Daten oder unverständlichen Fehlermeldungen. Deshalb ist es normalerweise besser, die Spalten mit ihrem Namen anzusprechen.

Wenn man allerdings 75 Spaltennamen eingeben muss, ist die Gefahr von Tippfehlern sehr groß, außerdem wird es sehr schnell unübersichtlich im Code und wer erkennt schon, ob man nicht einen vergessen hat. Deshalb sehe ich hier eine Ausnahmeindikation.

6 x 69 = 414 p-Werte anzufordern, fordert die Alphafehlerkummulation heraus. Zumal man bei n = 42 ja kaum eine Chance auf eine Alphafehlerkorrektur hat. Deshalb sollte man m. E. bestenfalls die Korrelationskoeffizienten deskriptiv berichten.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: eine MENGE Partialkorrelationen

Beitrag von jogo »

Hallo -R-atlos,

ich habe erstmal den Quelltext extrahiert:

Code: Alles auswählen

library(readxl)
alledaten <- read_excel("~/Desktop/Items & Ratings LG40_Cem_Aug 2017.xlsx", na = "NA")
library("Hmisc", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library("ICC", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library("MASS", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library("psy", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library("psych", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library("ppcor", lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
attach(alledaten)
swls.cue1.n.part = cbind(swls_ac_mw,cue_mw_1,age,sex)
pcor(swls.cue1.n.part)
(Du hattest den kompletten Output geliefert)
Wenn ich Dich richtig verstanden habe, soll nun an der Stelle von swls_ac_mw auch andere Spalten stehen können und an der Stelle von cue_mw_1 sollen auch andere Ratings stehen können, ja?
Kannst Du bitte den output von

Code: Alles auswählen

str(alledaten)
liefern und die Spalten benennen, die an den entsprechenden Stellen stehen sollen?

Gruß, Jörg
p.s.:
Ich habe gesehen, dass Du Deine Frage auch in einem anderen Forum gepostet hast. Der Anstand gebietet es, dass Du dort bei Deiner Frage darauf verweist, dass Deine Frage hier in diesem Forum schon einige Antworten hat.
p.p.s:
Hier noch schnell eine Code-Variante ohne das böse attach():

Code: Alles auswählen

library(readxl)
alledaten <- read_excel("~/Desktop/Items & Ratings LG40_Cem_Aug 2017.xlsx", na = "NA")
# ...
pcor(alledaten[, c("swls_ac_mw", "cue_mw_1", "age", "sex")])
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: eine MENGE Partialkorrelationen

Beitrag von jogo »

Dem Beispiel von Bernhard folgend könnte man auch programmieren:

Code: Alles auswählen

set.seed(0815)
beispieldaten <- data.frame(konstruktA = rnorm(42), konstruktB = rnorm(42), konstruktC = rnorm(42),
                            anderes = rnorm(42),
          rating1 = rnorm(42),  rating2 = rnorm(42), rating3 = rnorm(42), rating4 = rnorm(42))

K <- c("konstruktA", "konstruktB", "konstruktC")   # paste0("kostrukt", c("A", "B", "C"))
R <- c("rating1", "rating2", "rating3", "rating4") # paste0("rating", 1:4)

# Alle Spaltenkombinationen erhalten wir so
kombis <- expand.grid(K, R, stringsAsFactors = FALSE)
mapply(FUN=function(k,r) pcor(beispieldaten[, c(k, r, "anderes")]), kombis[,1], kombis[,2])
Um mal eine einfache Auswertungsfunktion zu nehmen (wie Bernhard):

Code: Alles auswählen

Ergebnis <- mapply(FUN=function(k,r)  cor.test(beispieldaten[, k], beispieldaten[, r]), kombis[,1], kombis[,2], SIMPLIFY = FALSE)
Gruß, Jörg
Antworten