Variablennamen extrahieren für Tabelle

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Werekorden
Beiträge: 83
Registriert: So Feb 04, 2018 7:52 pm

Variablennamen extrahieren für Tabelle

Beitrag von Werekorden »

Hi wie gehts euch in der Pandemie?

hab lange nichts gefragt aber das hole ich mal nach.

Ich möchte gerne die Variablennamen von 9 Variablen in eine neue Variable einfügen.
(H1, H2, H3, M1, M2, M3, L1, L2, L3 sind Variablen die auch Werte enthalten.)


Grund ist ich habe verschiedene Regressionstatistiken, die für jede Variable berechnet wurden und will das in eine Tabelle packen.

Ich will jetzt die Tabelle folgendermaßen erstellen ohne die Werte aus H1 usw. zu ziehen.

Name Slope y-int . . . .
H1 0.05 25
H2 0.04 24
H3 0.34 26
M1
.
.
.

die Variablen: Slope usw. habe ich aus dem Regressionsmodel folgendermaßen rausgezogen.

Code: Alles auswählen

slope <-
  c(
    fit_H1_1_sum$coefficients[2, 1],
    fit_H2_1_sum$coefficients[2, 1],
    fit_H3_1_sum$coefficients[2, 1]
  )
Hat da jemand eine Idee, funktioniert irgendwie nciht, der holt auch immer die Werte mit raus.

VG
Andreas
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Variablennamen extrahieren für Tabelle

Beitrag von bigben »

Hallo Andreas,

ich bin mir nicht sicher, wo das Problem liegt. Wenn Du für neun Variablen händisch schreibst

Code: Alles auswählen

slope <-
  c(
    fit_H1_1_sum$coefficients[2, 1],
    fit_H2_1_sum$coefficients[2, 1],
    fit_H3_1_sum$coefficients[2, 1]
  )
Warum schreibst Du dann nicht händisch

Code: Alles auswählen

meine_daten <- data.frame(
                     name = c("H1", "H2", H3"),
                     slope = c(
                         fit_H1_1_sum$coefficients[2, 1],
                         fit_H2_1_sum$coefficients[2, 1],
                         fit_H3_1_sum$coefficients[2, 1]
                       ))
Keine Frage, das Problem liegt auf meiner Seite. Ich könnte mir vorstellen, dass ein reproduzierbares Beispiel die Fragestellung noch klarer machen könnte.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Werekorden
Beiträge: 83
Registriert: So Feb 04, 2018 7:52 pm

Re: Variablennamen extrahieren für Tabelle

Beitrag von Werekorden »

Hi,

sorry, ja das händische Schreiben wäre eine Möglichkeit gewesen aber die Namen und Anzahl der Variablen können sich ändern und ich wollte es so einfach wie möglich machen und später daraus eine funktion machen.


Hier mal der vereinfachte Code und anbei die Excel-Datei.

Code: Alles auswählen

library(readxl)
library(kableExtra)

sample1 <- read_excel("/Pfad/Test.xlsx")

fit_H1.1 <- lm((H1 ~ Day),                  data=sample1)
fit_H2.1 <- lm((H2 ~ Day),                  data=sample1)
fit_H3.1 <- lm((H3 ~ Day),                  data=sample1)
fit_H1_1_sum<- summary(fit_H1.1)
fit_H2_1_sum<- summary(fit_H2.1)
fit_H3_1_sum<- summary(fit_H3.1)

slope <-
  c(
    fit_H1_1_sum$coefficients[2, 1],
    fit_H2_1_sum$coefficients[2, 1],
    fit_H3_1_sum$coefficients[2, 1]
  )
y_int <-
  c(
    fit_H1_1_sum$coefficients[1, 1],
    fit_H2_1_sum$coefficients[1, 1],
    fit_H3_1_sum$coefficients[1, 1]
  )
se_slope <-
  c(
    fit_H1_1_sum$coefficients[2, 2],
    fit_H2_1_sum$coefficients[2, 2],
    fit_H3_1_sum$coefficients[2, 2]
  )
slope_t <-
  c(
    fit_H1_1_sum$coefficients[2, 3],
    fit_H2_1_sum$coefficients[2, 3],
    fit_H3_1_sum$coefficients[2, 3]
  )
p_value <-
  c(
    fit_H1_1_sum$coefficients[2, 4],
    fit_H2_1_sum$coefficients[2, 4],
    fit_H3_1_sum$coefficients[2, 4]
  )
slope <- round(slope, digits = 4)
y_int <- round(y_int, digits = 2)
se_slope <- round(se_slope, digits = 4)
slope_t <- round(slope_t, digits = 2)
p_value <- round(p_value, digits = 2)

regression_stat <- tibble(slope, y_int, se_slope, slope_t, p_value)

regression_stat %>%
  mutate_all(linebreak) %>%
  kable("latex", booktabs = T,   
        caption = "Berechnung nach EP25-A Appendix C",
        col.names = linebreak(c("Slope", "Y-Inter", "SE Slope", "Slope t-stat", "p-value"), align = "r")) %>%
  kable_styling(latex_options = c("striped", "hold_position", "scale_down"))
Test.xlsx
(10.73 KiB) 69-mal heruntergeladen
Damit sollte es funktionieren. in die regression_stats soll jetzt eben für jede Variable die einzelnen Werte angezeigt werden.
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Variablennamen extrahieren für Tabelle

Beitrag von bigben »

Hallo Andreas,

also das war jetzt kein so tolles Beispiel. Erst eine Excel-Datei, die man nicht einfach mit read.table aus dem Netz laden kann, sondern für die man erst einen Platz auf der Platte suchen muss. Dann ein Spaltenname der ein Leerzeichen enthält, was in R alles unnötig schwer macht. Dann Einladen von zwei für den Kern der Frage unnötigen Libraries von denen ich eine extra installiert habe bevor ich gemerkt habe, dass man sie nicht braucht und dafür ein nicht lauffähiges Beispiel, weil nicht alle benötigten Libraries deklariert sind und am Ende steht da Latex in meiner Konsole.

Da fasse ich mich jetzt mit der Antwort kurz:

- Fang mit den Spaltennamen an, statt sie am Ende zu addressieren
- Nutze das broom package

Code: Alles auswählen

library(broom)
library(flextable)

sample1 <- read.table(header = TRUE, dec = ",", text = 
"Day	H1	H2	H3	H4	M1	M2	M3	M4	L1	L2	L3	L4	PK1	PK2	Pk3
0	25,9874	26,01875	25,95655	25,95165	29,2727	29,4116	29,2389	29,30505	32,76275	32,69395	32,6963	32,80915	23,64346667	26,9035	30,64406667
57	25,70225	25,7461	25,77375	25,76555	29,13705	29,13665	29,2091	29,0638	32,58625	32,8572	32,59715	32,20532	24,14003333	29,41563333	31,2637
98	25,70600573	25,72381592	25,70797857	25,71254603	28,98645592	29,21009572	29,09545708	29,18635877	32,64453761	32,70707448	32,39242554	32,69418971	25,33333333	30,01	34,20666667
189	25,73180667	25,63853333	25,68836	25,64337333	29,04110333	28,84034667	29,07556667	29,01635667	32,66040667	32,36568333	32,64399333	32,49889	22,86015	26,80275	30,504258
286	24,43987783	24,59473801	24,50444539	24,55189578	26,89529673	26,92798169	26,99993324	26,85812505	30,19608625	30,45819219	30,45007133	30,36466662	23,07262484	26,24733263	30,80879011
380	25,73180667	25,63853333	25,68836	25,64337333	29,04110333	28,84034667	29,07556667	29,01635667	32,66040667	32,36568333	32,64399333	32,49889	22,86015	26,80275	30,504258
")

spalten <- names(sample1)[-1]
regressionen <- lapply(spalten, function(spalte) tidy(lm(paste(spalte,"~ Day"), data = sample1))[2,])
regressionen <- do.call(rbind, regressionen)
regressionen$term <- spalten
flextable(regressionen)
print(regressionen)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Werekorden
Beiträge: 83
Registriert: So Feb 04, 2018 7:52 pm

Re: Variablennamen extrahieren für Tabelle

Beitrag von Werekorden »

Hi Bernhard,

arghh da sieht man es mal wieder. Ich habe die hinteren Variablen noch garnicht angeschaut gehabt. Die Datei kam so vom Kollegen, deshalb auch Excel.
Das Prinzip mit read.table kenn ich nicht. Gibts da eine gute Anleitung, gerne mache ich das in Zukunft so. Auch hier Danke schonmal für den Tipp.

Aber wow, ich habe ewig viel Code um das gleich Ergebnis gebraucht. Da mus ich jetzt erst einmal durchsteigen.

Vielen ielen Dank,

Ich werde dann mal ein wenig ausprobieren.

VG
Andreas
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Variablennamen extrahieren für Tabelle

Beitrag von bigben »

Hallo Andreas,
Werekorden hat geschrieben: Mi Aug 04, 2021 10:19 pmAber wow, ich habe ewig viel Code um das gleich Ergebnis gebraucht.
Das liegt zum Teil daran, dass Du die Funktion broom::tidy noch nicht kanntest, die halt schon ziemlich genau das macht, was Du umständlich von Hand gemacht hast. Das liegt zum andere Teil daran, dass Du viel Code mit copy&paste erstellt hast, was beim Erstellen ganz praktisch ist, nachher aber schwer anzupassen und blöd in der Fehlersuche ist. Versuche einfach jedes Mal, wenn Du einen Code Abschnitt kopierst zu überlegen, ob man dafür nicht eine Schleife programmieren oder eine Funktion schreiben könnte. Im Laufe der Zeit wird es Dir viel leichter fallen. Das heißt natürlich nicht, dass nicht ausnahmesweise auch mal copy&paste-Code angemessen sein kann.

Da mus ich jetzt erst einmal durchsteigen.
Ja, ich gebe zu, da sind mehrere Prinzipien zu verstehen -- aber es lohnt sich. Es lohnt sich, eine "ganze" Fragestellung und nicht nur eine Teilfragestellung zu posten, dann kann man von Anfang an den besseren Weg gehen.

Zu Deiner Ausgangsfrage, wie man aus einer schon vorhandenen linearen Regression den Prädiktor extrahiert: das geht auch

Code: Alles auswählen

> a = 1:4
> b = 1:4
> names(lm(a ~ b)$coeff)[2]
[1] "b"
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Werekorden
Beiträge: 83
Registriert: So Feb 04, 2018 7:52 pm

Re: Variablennamen extrahieren für Tabelle

Beitrag von Werekorden »

Hallo Bernhard,

so habe es mal ein wenig durchdacht und nachgelesen.

Code: Alles auswählen

regressionen <- lapply(spalten, function(test) tidy(lm(paste(test,"~ Day"), data = sample1))[2,])
lapply sagt einfach nur, mache eine Funktion und nutze x=spalten dort wo "test" geschrieben wurde. Das Reinkopieren des x-Wertes wird mit "paste" durchgeführt und danach läuft Funktion "lm" ab und wir ziehen mit tidy [2,] die zweite Zeile der Summary raus.

Jetzt finde ich leider wenig infos zur tidy Funktion an sich, viel zu broom, purr usw.

Wenn ich jetzt den y-Intercepter rausziehen will, dann mache ich es so:

Code: Alles auswählen

regressionen <- lapply(spalten, function(test) tidy(lm(paste(test,"~ Day"), data = sample1))[1,2])
Aber ich bekomme es nicht hin sowohl die ganze zweite Zeile und den Y-Intercepter rauszuziehen:

Code: Alles auswählen

regressionen <- lapply(spalten, function(test) tidy(lm(paste(test,"~ Day"), data = sample1))[2,], [1,2])
klappt z.B. nicht.


Dann dachte ich mir, ok mach es dir einfach und mache mehrere Einzelschritte um es zu verstehen, also habe ich folgendes probiert:

Code: Alles auswählen

test <- lapply(spalten, function(test)summary(lm(paste(test, "~Day"), data = sample1)))
tidy(test)
Das klappt aber nicht, es gibt den Fehler: No tidy method recognized for this list.

Code: Alles auswählen

test <- lm(H1~Day, data = sample1)
tidy(test)
klappt, also muss es mit lapply zu tun haben und dem x aber ich komme nicht darauf was es ist.

So ich hoffe es ist nicht zu chaotisch geschrieben.

VG,
Andreas
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Variablennamen extrahieren für Tabelle

Beitrag von bigben »

Hallo Andreas,

lapply ist einfach nur eine Variante, eine Schleife zu schreiben. Man könnte es etwas umständlicher mit for schreiben.

Code: Alles auswählen

lapply(1:12, ...)
führt eine Funktion mit den Werte von 1 bis 12 aus und

Code: Alles auswählen

lapply(spalten, ...

führt für jedes Element in dem Vector spalten die übergebene Funktion einmal aus und speichert die Ergebnisse in einer Liste. In diesem Fall wird für jeden Spaltennamen in spalten eine Funktion ausgeführt, die ein Tibble, eine spezielle Form von Dataframe erstellt. Mit

Code: Alles auswählen

do.call(rbind, regressionen)
werden alle die von lapply erzeugten Dataframes mit der Function rbind aneinandergeklettet.

Die Funktion broom::tidy zieht die Daten zu den Koeffizienten aus einer Regression und schreibt sie in ein Tibble/einen speziellen Dataframe, damit man sie im Programm leicht greifen kann, ohne den von Dir beschrittenen Umweg über summary zu gehen:

Code: Alles auswählen

head(iris)
m <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris)
broom::tidy(m)
Und weil die Ergebnisse der Regression jetzt schön ordentlich (tidy) in einem Dataframe stehen, kann man sie da mit eckigen Klammer wie bei jedem anderen Dataframe einsehen:

Code: Alles auswählen

broom::tidy(m)[1,]  # Daten zum Intercept
broom::tidy(m)[2,]  # Daten zum ersten Prädiktor
broom::tidy(m)[3,]  # Daten zum zweiten Prädiktor
broom::tidy(m)[,2]  # Höhe der Koeffizienten
broom::tidy(m)[,3]  # Standardfehler der Koeffizienten
HTH,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Variablennamen extrahieren für Tabelle

Beitrag von bigben »

und weiter...
Werekorden hat geschrieben: Sa Aug 07, 2021 9:37 pmDann dachte ich mir, ok mach es dir einfach und mache mehrere Einzelschritte um es zu verstehen, also habe ich folgendes probiert:

Code: Alles auswählen

test <- lapply(spalten, function(test)summary(lm(paste(test, "~Day"), data = sample1)))
tidy(test)
Wenn innerhalb der lapply - Schleife eine Funktion aufgerufen wird, die mehr als nur einen Befehl enthält dann müssen diese Befehle als Block in geschweiften Klammern zusammengefasst werden:

Code: Alles auswählen

spalten <- names(sample1)[-1]
regressionen <- lapply(spalten, 
                       function(spalte){
                           print("Juhu, die namenlose Funktion wurde aufgerufen!")
                           meine_regression <- lm(paste(spalte,"~ Day"), data = sample1)
                           das_tidy_davon <- tidy(meine_regression)
                           beta_0 <- das_tidy_davon[1,]
                           beta_1 <- das_tidy_davon[2,]
                           print(beta_0)
                           print(beta_1)
                           print("Ende der namenlosen Funktion. Jetzt ist'S rum.")
                           return(cbind(beta_0, beta_1))
                       })
  
} 
regressionen <- do.call(rbind, regressionen)

print(regressionen)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Werekorden
Beiträge: 83
Registriert: So Feb 04, 2018 7:52 pm

Re: Variablennamen extrahieren für Tabelle

Beitrag von Werekorden »

Hallo Bernhard,

ah großartig. Ich hatte es mir fast schon gedacht, dass man das getrennt sich holt, aber das man das so in die Funktion mit reinnimmt ist super und jetzt weiß ich auch warum ich Funktionen mit geschweiften Klammern gesehen habe und wunder mich nicht mehr warum deine am Anfang noch keine hatte.


Hier mal meine Variante damit die Variablen in der richtigen Reihenfolge sind, umbenannt und auf das gewünschte Maß gerundet werden usw.. Beim Runden könnte ich bestimmt wieder eine Funktion machen, das werde ich dann mal demnächst ausprobieren:

Code: Alles auswählen

spalten <- names(sample1)[-1]
regressionen <- lapply(spalten, 
                       function(spalte){
                         meine_regression <- lm(paste(spalte,"~ Day"), data = sample1)
                         das_tidy_davon <- tidy(meine_regression)
                         beta_0 <- das_tidy_davon[1,2]
                         beta_1 <- das_tidy_davon[2,]
                         return(cbind(beta_0, beta_1))
                         
                       })

#rbind sorgt dafür das jede Zeilen jedes Tibbles in eine neuen tibble eingesetzt werden und zwar spezifisch für jede Spalte.
regressionen <- do.call(rbind, regressionen)
#Die Werte der Variable regressionen$term werden durch die Werte von "spalten" ersetzt
regressionen$term <- spalten

#Umbenennen der Variablen da sonst doppelte Variablen die flextable verhindern
names(regressionen)[1] <- "y_int"
names(regressionen)[3] <- "slope"
names(regressionen)[4] <- "se_slope"

#Runden nach Norm
regressionen$p.value <- round(regressionen$p.value, digits = 2)
regressionen$y_int <- round(regressionen$y_int, digits = 2)
regressionen$slope <- round(regressionen$slope, digits = 4)
regressionen$se_slope <- round(regressionen$se_slope, digits = 4)
regressionen$statistic<- round(regressionen$statistic, digits = 2)

#Verschiebt die Variable term an erste Stelle, da dies die Probennamen sind
regressionen <- regressionen %>% select(term, y_int, slope, se_slope, statistic, p.value) 
Danke auf jedenfall bis hier hin. Ich schaue mir jetzt mal an wie ich mit Funktionen oder facets für jede Variable einen passenden Plot in ggplot2 erstellen und die alle schön nebeneinander anordnen kann, Stichwort facet_grid.

Ich bin weitehrin happy, wie ich langsam immer mehr das Prinzip von R verstehe.
Danke für eure großartige Hilfe. Ich darf sagen dieses Forum ist wirklich top.

VG
Andreas
Antworten