Rmd

Aus Rohdaten müssen häufig die eigentlichen Variablen generiert werden, die in den Berechnungen, den statistischen Verfahren verwendet werden. Beispiele sind das Bilden von Fragebogenskalen aus im Datensatz vorliegenden Einzelitems, gemittelte Reaktionszeiten aus in den Daten vorliegenden Einzelreaktionen unter einer bestimmten experimentellen Bedingung etc.

Teilweise ist es auch nötig, selbst einen Weg zu finden, um aus vorliegenden Variablen eine inhaltlich sinnvolle Kenngröße zu generieren.

Meist sind Transformationen Operationen, mit denen neue Daten (Variablen) erzeugt werden. Oft ist es gut oder sogar nötig, diese neu erzeugten Variablen als Spalte in einen bestehenden Dataframe zu integrieren.

Die Darstellungen hier konzentrieren sich auf die generellen Techniken zur Datenmodifikation. Bezogen auf die Transformationen in Dataframes gibt es eine eigene Unit. html Es gibt gewisse Überschneidungen bzw. Ergänzungen mit den Darstellungen hier.

Für Datenaufbereitung empfehlen wir den Einsatz von dplyr. Auch dort finden sich entsprechende Hinweise und Beispiele zur Datenaufbereitung.

Es ist essenziell, ein Grundverständnis der Datentypen von R zu haben. Siehe Unit Unit

Datentypen und Umgang damit

data_types dataframe

Slicing (subsetting)

transformation_base

dataframe

Datentransformation mit dem Base-System

Zusammenbauen: cbind(), rbind() logic vector als Basis für Filter

transformation_base

Datentransformation mit dplyr

dplyr

long wide und tidyr

long_wide

  • tidy data

In den meisten Statistik-Softwarepaketen gilt die Regel, dass alle Daten einer Beobachtung (Vp) in einer Zeile auftauchen müssen, auch bei Messwiederholungen.

In R gibt es das Long-Format, in dem Messwiederholungen mit einer ‘Gruppierungsvariable’ Beobachtung (Vp) als separate Zeilen in einem Dataframe auftauchen. Die Messwiederholung wird dabei in einer ‘formula’ definiert und entsprechend statistisch behandelt.

R-Cookbook Artikel hierzu

joining data

join

Missing Data

miss

Umformatierung von Datensätzen: Einlesen, transformieren, speichern

wrapper function write.delim()

Wir schaffen uns eine neue Funktion write.delim() analog zu read.delim(), um DataFrames wegzuschreiben

# we get our working directory. This is, where we write to by default.
getwd()
## [1] "/Users/pzezula/ownCloud/lehre_ss_2021/unit/transformation"
# we define a new function called write.delim()
write.delim <- function(x, ...){
    write.table(x, quote=F, sep="\t", row.names=F, ...)
}
# we get some data
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/div/jump_in.txt")
# we sort dd by gender and height
require(dplyr)
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
dd <- dplyr::arrange(dd, gender, height)

# we save modified dataframe dd to the working directory
write.delim(dd, "gar.txt")

# we save it in csv format with Separator ','
write.csv(dd, "jump_in.csv")
# we save it in csv format with Separator ';'
write.csv2(dd, "jump_in_2.csv")

Entwicklung eigener Ansätze für Problemlösungen durch Transformationen

“Ausgleich” von Geschlechtsunterschieden bei Neurotizismus-Werten

Women consistently report higher Neuroticism and Agreeableness.

Angenommene Werte: Skalenwerte des BFI-10.

cf

Erzeugen Sie eine Spalte neur_e im Data-Frame df, in der die um den Geschlechtsunterschied bereinigten Neurotizismuswerte stehen.

set.seed(42)
neur.f <- rnorm(100, mean=2.58, sd=.92)
neur.m <- rnorm(100, mean=2.22, sd=.79)
df <- data.frame(
    gender = c(rep('f', 100), rep('m',100)),
    neur = c(neur.m, neur.f)
  )
t.test(neur ~ gender, data=df)
## 
##  Welch Two Sample t-test
## 
## data:  neur by gender
## t = -3.8411, df = 183.08, p-value = 0.0001687
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.6948043 -0.2232472
## sample estimates:
## mean in group f mean in group m 
##        2.150888        2.609914
write.table(df, 'neur_gender.txt', quote=F, sep="\t", row.names=F)

Einer von vielen möglichen Lösungsansätzen

[res_begin:gender]

  • gruppenspezifischen Mittelwert und Gesamtmittelwert ermitteln
  • bei jeder einzelnen Frau die Differenz des Frauen-Mittelwertes zum Gesamtmittelwert aufaddieren
  • bei jedem einzelnen Mann die Differenz des Männer-Mittelwertes zum Gesamtmittelwert abziehen
require(dplyr)
mean.f <- df %>% dplyr::filter(gender == 'f') %>% summarize(mean(neur))
mean.f <- as.numeric(mean.f)
mean.f
## [1] 2.150888
mean.m <- df %>% dplyr::filter(gender == 'm') %>% dplyr::select(neur) %>% summarize(mean(neur))
mean.m <- as.numeric(mean.m)
mean.m
## [1] 2.609914
# grand mean neuroticism
mean.fm <- df %>% summarize(mean(neur))
mean.fm <- as.numeric(mean.fm)
df$neur_e <- NA
df.f <- df %>% dplyr::filter(gender == 'f') %>% dplyr::mutate(neur_e = neur + (mean.fm - mean.f))
df.m <- df %>% dplyr::filter(gender == 'm') %>% dplyr::mutate(neur_e = neur + (mean.fm - mean.m))
df <- rbind(df.f, df.m)
t.test(neur_e ~ gender, data=df)
## 
##  Welch Two Sample t-test
## 
## data:  neur_e by gender
## t = 0, df = 183.08, p-value = 1
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.2357785  0.2357785
## sample estimates:
## mean in group f mean in group m 
##        2.380401        2.380401

[res_end:accept]

Interpolieren

… bei missing values in Messwiederholungsverläufen,

Eine Erhebung über 7 Jahre hat aus politischen Gründen in den Jahren 4 und 5 nicht stattgefunden. Die beiden fehlenden Jahre sollen durch geeignete Werte auf individueller Basis geschätzt werden.

require(tidyverse)
## Loading required package: tidyverse
## ── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.2     ✓ purrr   0.3.4
## ✓ tibble  3.0.1     ✓ stringr 1.4.0
## ✓ tidyr   1.0.2     ✓ forcats 0.4.0
## ✓ readr   1.3.1
## Warning: package 'ggplot2' was built under R version 3.6.2
## Warning: package 'tibble' was built under R version 3.6.2
## Warning: package 'purrr' was built under R version 3.6.2
## ── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
dd <-tibble(
  subj = as.factor(c(1,2,3,4,5)),
  y1   = c( 2,  0,  5,  4,  7),
  y2   = c( 6,  2,  7, 12,  9),
  y3   = c( 7,  9,  9, 15, 15),
  y4   = c(NA, NA, NA, NA, NA),
  y5   = c(NA, NA, NA, NA, NA),
  y6   = c(14, 18, 15, 22, 25),
  y7   = c(18, 22, 19, 29, 23)
)
# we convert dd to long format
dd.l <- dd %>% tidyr::gather(year, score, y1:y7) %>% dplyr::arrange(subj)
# and show a graph with the gap between the missing years
dd.l %>% ggplot2::ggplot(aes(x=year, y=score, group=subj, color=subj)) + ggplot2::geom_line() + ggplot2::geom_point(size=5) 
## Warning: Removed 10 rows containing missing values (geom_point).

# we interpolate the missings
dd %>% dplyr::mutate(diff_3_6 = y6 - y3, y4 = y3 + diff_3_6/3, y5 = y6 - diff_3_6 / 3) -> dd
# we convert dd to long format
dd.l <- dd %>% tidyr::gather(year, score, y1:y7) %>% dplyr::arrange(subj)
# and show a graph with the gap between the missing years
dd.l %>% ggplot2::ggplot(aes(x=year, y=score, group=subj, color=subj)) + ggplot2::geom_line() + ggplot2::geom_point(size=5) 

# btw: we could also think of an individual regression line

Akzeptanz-Score für eine Lehrveranstaltung

Die Akzeptanz einer Lehrveranstaltung soll durch verschiedene Indikatoren erfasst werden.

  • Anzahl der nicht wahrgenommenen Termine (%)
  • Aktive Beteiligung in LV (0-100)
  • konstruktive Beiträge (0-100)
  • destruktive Kritik (0-100)

Es soll ein Akzeptanzscore ‘acceptance’ entwickelt werden, der alle Indikatoren geeignet miteinander verrechnet. Besonders wichtig ist hierbei die Anzahl der Fehltermine. Diese besondere Gewicht soll in dem Score zum Ausdruck kommen. Der Akzeptanzscore soll in Schulnoten (1-6) ausgedrückt werden. Eine 1 ist die höchste Akzeptanz. Begründen Sie Ihren Score und seine Eignung als Akzeptanzscore.

# create sample dataframe
df <-data.frame(
  subj   =c(1,2,3,4,5),
  missing = c( 2,  0, 80,  5,  3),
  active  = c(90, 10,  2, 20, 80),
  constr  = c(20, 90,  5, 40, 75),
  destr   = c(10,  0, 90,  2,  5),
  comment = c('spricht viel', 'still aber dabei', 'steigt aus', 'im Mittel', 'aktiv dabei')
)
df
##   subj missing active constr destr          comment
## 1    1       2     90     20    10     spricht viel
## 2    2       0     10     90     0 still aber dabei
## 3    3      80      2      5    90       steigt aus
## 4    4       5     20     40     2        im Mittel
## 5    5       3     80     75     5      aktiv dabei

Einer von vielen möglichen Lösungsansätzen

[res_begin:accept]

df <-data.frame(
  subj   =c(1,2,3,4,5),
  missing = c( 2,  0, 80,  5,  3),
  active  = c(90, 10,  2, 20, 80),
  constr  = c(20, 90,  5, 40, 75),
  destr   = c(10,  0, 90,  2,  5),
  comment = c('spricht viel', 'still aber dabei', 'steigt aus', 'im Mittel', 'aktiv dabei')
)
require(dplyr)
# we invert negative items
# we copy missing to get increased weight
# we select only relevant vars
# we switch to rowwise processing
# we apply rowMeans
# we save result to a new variable
df %>% mutate(i_missing = 100 - missing, i_missing2 = i_missing, i_destr = 100 - destr) %>% 
    select(i_missing, i_missing2, active, constr, i_destr) %>% rowwise %>% rowMeans -> df$acceptance_percentage
# we convert percentage to grades using full range
(100 - df$acceptance_percentage) / 20 + 1
## [1] 2.04 2.00 5.43 2.52 1.56
# we can round it
round((100 - df$acceptance_percentage) / 20 + 1)
## [1] 2 2 5 3 2

[res_end:accept]

Das Problem von Benotungskulturen beim Vergleich von MA-Bewerbern aus verschiedenen Universitäten

Bei der Vergabe von Studienplätzen gibt es für die Zulassung von Bewerberinnen und Bewerber an einer Ziel-Hochschule das Problem, dass verschiedene Herkunfts-Hochschulen ganz unterschiedliche Benotungskulturen haben. Eine 1.3 der einen Hochschule kann somit eine mittelmäßige Benotung sein, eine 1.7 einer anderen aber eine Spitzennote. Entwickeln Sie einen Ansatz, die Noten vergleichbarer zu machen. Generieren Sie für jede Person des Datensatzes eine Note, die die Leistungen der Personen besser vergleichbar macht.

grade1, grade2 und grade3 seien Noten in Psychologie in verschiedenen Fächern, z. B. Methoden, Diagnostik, angewandte Psychologie.

# create sample dataframe
df <-data.frame(
  subj   = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
  uni    = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
  grade1 = c(1.0, 2.7, 3.7, 1.3, 1.7, 1.0, 3.3, 4.0, 3.7),
  grade2 = c(4.0, 3.0, 1.3, 1.3, 1.0, 1.3, 2.7, 4.0, 3.3),
  grade3 = c(1.3, 2.3, 2.7, 1.0, 1.3, 1.3, 2.3, 3.7, 3.0)
)
df
##   subj uni grade1 grade2 grade3
## 1    1   1    1.0    4.0    1.3
## 2    2   1    2.7    3.0    2.3
## 3    3   1    3.7    1.3    2.7
## 4    4   2    1.3    1.3    1.0
## 5    5   2    1.7    1.0    1.3
## 6    6   2    1.0    1.3    1.3
## 7    7   3    3.3    2.7    2.3
## 8    8   3    4.0    4.0    3.7
## 9    9   3    3.7    3.3    3.0

Ein möglicher Lösungsansatz

[res_begin:grades]

# create sample dataframe
df <-data.frame(
  subj   = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
  uni    = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
  grade1 = c(1.0, 2.7, 3.7, 1.3, 1.7, 1.0, 3.3, 4.0, 3.7),
  grade2 = c(4.0, 3.0, 1.3, 1.3, 1.0, 1.3, 2.7, 4.0, 3.3),
  grade3 = c(1.3, 2.3, 2.7, 1.0, 1.3, 1.3, 2.3, 3.7, 3.0)
)
#todo
# individual mean of grades
require(dplyr)
# inner select works
mutate(df, grade.mean = rowMeans(select(df, contains("grade")), na.rm = TRUE)) -> df.n
# chained select works
df %>% select(contains("grade")) %>% mutate(gr.mean = rowMeans(., na.rm = TRUE)) -> df.n
# we could alternatively discard the source variables
df %>% select(contains("grade")) %>% transmute(gr.mean = rowMeans(., na.rm = TRUE)) -> df.n


# we add result to df in a new column named 'gr.mean'
df$gr.mean <- df.n[,1]
df$gr.mean <- df.n[['gr.mean']]


# : works
df %>% select(grade1:grade3) %>% mutate(gr.mean = rowMeans(., na.rm = TRUE)) -> df.n



# using mean() which needs an input vector
df %>%dplyr::select(contains("grade")) %>% dplyr::rowwise() %>% dplyr::mutate(av_grade = mean(c(grade1, grade2, grade3))) -> df.n
df %>% dplyr::rowwise() %>% dplyr::mutate(av_grade2 = mean(c(grade1, grade2, grade3))) -> df.n

df %>% dplyr::rowwise() %>% dplyr::mutate(av_grade3 = mean(c(select(., grade1:grade3)))) -> df.n
## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA

## Warning in mean.default(c(select(., grade1:grade3))): argument is not numeric or
## logical: returning NA
rm(df.n)
# rowMeans only works on data frames
df %>%dplyr::select(contains("grade")) %>% dplyr::rowwise() %>% dplyr::mutate(av_grade = rowMeans(data.frame(grade1, grade2, grade3))) -> df.n




# Versuche
df <- expand.grid(x = 1:3, y = 3:1, z = 4:6)
df %>% rowwise() %>% do(i = seq(.$x, .$y)) %>% summarise(n = length(i))
## # A tibble: 27 x 1
##        n
##    <int>
##  1     3
##  2     2
##  3     1
##  4     2
##  5     1
##  6     2
##  7     1
##  8     2
##  9     3
## 10     3
## # … with 17 more rows
df %>%dplyr::select(contains("grade")) -> df.g


require(dplyr)
ds <- tbl_df(mtcars)

Bedenkenswertes:

  • wie repräsentativ sind die Personen für ihre jeweilige Hochschule?
  • wie repräsentativ sind die Studierenden, die sich beworben haben, für alle Studierenden des Faches der jeweiligen Hochschule? Sind die vorliegenden Studierenden eine ganz spezielle, ggf. verzerrte Auswahl aller Studierenden?
  • Bilden die Noten u. U. tatsächliche Unterschiede der Prüfungsleistungen zwischen den Hochschulen ab?

[res_end:grades]

Spannbreite von Reaktionszeiten bei variabler Menge von Reaktionen

In einem Experiment haben die Versuchspersonen unterschiedlich häufig reagiert.

  • Sie wollen wissen, welche Person die wenigsten und welche die meisten Reaktionszeiten hat.
  • Sie wollen wissen, wie groß die Spannbreite bei den Personen ist, also der Unterschied zwischen schnellster und langsamster Reaktionszeit.

Angenommen, normalerweise wurden 25 Reaktionen erwartet. - Entwickeln Sie eine prozentuale Reaktionshäufigkeit (Under- Overachiever)

Robuste Schätzer: Von einer Menge von Reaktionszeiten soll pro Versuchsperson eine fixe Anzahl von extremen Werten nicht in die Auswertungen eingehen.

Dieselbe Grundidee soll über einen Prozentsatz gelöst werden. Beispiel: die 2% schnellsten und die 5% langsamsten Reaktionszeiten sollen nicht in eine Analyse eingehen.

df <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_transf_rt.txt")
df
##    subj  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 V11 V12 V13 V14 V15 V16 V17 V18
## 1     1 413 484 363 420 492 497 437 476 393 388 449 414 405 373 428 437 401 407
## 2     2 447 406 438 434 486 513 398 570 375 560 457 435 572 437 482 448 431  NA
## 3     3 435 402 454 456 501 431 383 423 366 376 380 346 423 456 415 372 456 344
## 4     4 458 450 458 415 409 404 383 344 420 401 472 360 345 451 403 500 454 494
## 5     5 341 363 404 410 458 392 400 393 413 453 399 416 366 409 376 478 374 370
## 6     6 446 424 387 479 445 453 349 511 462 368 428 437 408 428 359 455 415 431
## 7     7 485 487 443 442 433 540 362 529 353 441 362 461 517 452 457 331  NA  NA
## 8     8 569 550 367 554 539 475 515 484 565 530 548 474 546 560 558  NA  NA  NA
## 9     9 432 418 497 440 396 476 526 405 377 496 475 444 349 484 477 487  NA  NA
## 10   10 406 372 399 452 478 399 386 461 384 472 424 415 447 411 416 405 490 458
##    V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30
## 1  407 370 427 457 364 397 360  NA  NA  NA  NA  NA
## 2   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 3   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 4  468  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 5  405 411 360 403  NA  NA  NA  NA  NA  NA  NA  NA
## 6  437 490 446 464 441 431 397 425 383 445 511  NA
## 7   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 8   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 9   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## 10 405 390  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

Lösungsansatz

[res_begin:rt]

df <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_transf_rt.txt")
# we define a function to get the number of NA
n.of.na <- function(x) length(which(is.na(x)))
# we apply this funciton rowwise
df$n.na <- apply(df[2:31], 1, n.of.na)
require(dplyr)
#df %>% select(V1:V30) %>% rowwise %>% mutate(nna = n.of.na(c(V1,V2,V30)))
#todo
# {}todo
## von Joshua
ddf <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_transf_rt.txt")
# we define a function to get the number of NA
n.of.na <- function(x) length(which(is.na(x)))
# we apply this function rowwise
ddf$n.na <- apply(ddf[2:31], 1, n.of.na)
#dieser Befehl fügt einfach die ANzahl fehlender Reaktionszeite ein
require(dplyr)
#für a)
dplyr::percent_rank(ddf$n.na)->ddf$ProzRang #ginge glaube ich auch in mutate, geht so aber fixer.
#Dass zwei werte den gleichen Rang kriegen können, ist durchaus ok, würde dich ja interessieren, wenn zwei leute die wenigsten zeiten haben
#Prozentränge, weil deren Minimum immer 0, und Maximum immer 100 ist, dann muss man den maximalrang nicht noch aus der stichprobengröße rausholen

dfMeisteZeiten<-dplyr::filter(ddf, ddf$ProzRang==0)
dfWenigsteZeiten<-dplyr::filter(ddf, ddf$ProzRang==1)
#Wer ist das denn nun?
#die meisten Zeiten hat Subjekt NUmmer:
dfMeisteZeiten$subj
## [1] 6
#und die wenigsten hat SUbjekt NUmmer:
dfWenigsteZeiten$subj
## [1] 8
#für b)
#mutate(rowwise(ddf),MinimumRT = min(c(V1:V30),na.rm=T))->ddf
#das funktioniert nicht. hab jetzt 1,5 Stunden dran gekämpft, irgendwie nehmen rowwise-Befehle keine na.rm-Argumente an.
#Wenn du das so in der Klausur schreibst, und das dazu sagst, sollte das für alle Punkte reichen, das ist echt tiefschwarze Programmiermagie

#für c)
mutate(rowwise(ddf), ProzErwart = (30-n.na)/25)->ddf
#Und dann wie bei dir, mehr als 1 Over-, weniger Underachiever

[res_end:grades]

Beispiele

Beispiel: Vergleich körperlicher Attraktivität

Vergleich körperlicher Attraktivität

BMI und Wellbeeing

bmi_wellbeeing

Check, Points to see

  • Beobachtungseinheit what is my observation, countries can be observations if we consider the world or if we compare world regions cities might be the observations within a country, persons aren’t in this case, although persons live in cities

  • verschieben, strecken, stauchen, z-transformieren

  • zwei Richtungen, zwei Möglichkeiten

dd <- readRDS(gzcon(url("http://md.psych.bio.uni-goettingen.de/mv/data/div/parms_data.rds")))
psych::describe(dd$ev)
##    vars   n mean   sd median trimmed  mad  min   max range skew kurtosis   se
## X1    1 300 5.23 2.48   5.26    5.27 2.78 -1.7 10.33 12.03 -0.2    -0.77 0.14
# move ev so that it varies between -5 and +5, shift is usually an addition or subtraction, 
# no stretching, no compressing, distances stay the same
# transformation base is the scale range
dd$ev.c <- dd$ev -5
# centering rv, no rescaling, movement (distance) depends on the empirical mean
dd$rv.c <- dd$rv - mean(dd$rv)
# stretch/shrink relations is done with * and /
# recalculate dd$ev to a range between 0 and 100
dd$ev.100 <- dd$ev * 10
# rescaling explicitly
dd$rv.zm <-  (dd$rv - mean(dd$rv)) / sd(dd$rv)
# ... or using scale()
dd$rv.z  <- scale(dd$rv)
# rescale rv to be a normal distribution with mean 50 and sd 10, T-values
dd$rv.t <- scale(dd$rv) * 10 + 50
Rmisc::summarySE(dd, "ev.c")
##    .id   N      ev.c       sd        se        ci
## 1 <NA> 300 0.2293757 2.477558 0.1430419 0.2814963
psych::describe(dd[,6:11])
##        vars   n  mean    sd median trimmed   mad    min    max  range  skew
## evl       1 300  4.01  2.70   3.89    3.99  2.84  -5.70  13.00  18.70  0.17
## evh       2 300  5.24  2.98   5.19    5.23  3.97  -1.93  11.38  13.30  0.03
## ev.c      3 300  0.23  2.48   0.26    0.27  2.78  -6.70   5.33  12.03 -0.20
## rv.c      4 300  0.00 15.07   2.48    1.03 13.23 -48.21  40.71  88.92 -0.66
## ev.100    5 300 52.29 24.78  52.63   52.74 27.77 -17.04 103.28 120.33 -0.20
## rv.zm     6 300  0.00  1.00   0.16    0.07  0.88  -3.20   2.70   5.90 -0.66
##        kurtosis   se
## evl        0.44 0.16
## evh       -1.09 0.17
## ev.c      -0.77 0.14
## rv.c       0.34 0.87
## ev.100    -0.77 1.43
## rv.zm      0.34 0.06
  • Verhältnisse sind Brüche

  • Dreisatz, was sind die 100 Prozent

  • Verteilungsform verändern quadrieren, wurzeln, logarithmieren, …

  • Kreativität, etwas neu denken individuelles lm()

# Leistungen an Tagen, zwei fehlen
rv <- c(10, 11, NA, NA, 14, 17, 18, 20)
dd <- tibble(
  rv = rv,
  tt = 1:8
)
mm <- lm(rv ~ tt, data=dd)
dd.n <- tibble(tt = 1:length(rv))
predict.lm(mm, dd.n)
##         1         2         3         4         5         6         7         8 
##  9.570815 10.987124 12.403433 13.819742 15.236052 16.652361 18.068670 19.484979
  • Argumentieren: Kombination aus Alltagswissen und statistischen Kenntnissen