Rmd

Transformationen Startseite: transformation

Slicing

Slicing: Zugriff auf Teile von Datenobjekten mit Hilfe der Slicing-Klammern [...]. Basis für Transformationen jeder Art ist die Auswahl der Daten, die transformiert werden sollen.

Slicing bei Vektoren

Das Folgende gilt implizt auch für Spalten von Dataframes und wird dargestellt in der unit dataframe

# zwei Datenvektoren:
sex <- c(1,2,2,1,1,1,2,2,2,1,2,2,1,1,1,2,1)
age <- c(15, 17, 22, 32, 12, 18, 24, 34, 23, 22, 29, 15, 17, 20, 21, 23, 19)

# die ersten 5 Alterswerte:
age[1:5]
## [1] 15 17 22 32 12
# die Werte 2, 5, 7-10 des Vektors
age[c(2, 5, 7:10)]
## [1] 17 12 24 34 23 22
# Bedingter Zugriff (Filter)
# die Werte unter 20
age[age < 20]
## [1] 15 17 12 18 15 17 19
# Zugriff kann auch erfolgen über anderen Vektor und Bedingung hieraus (Filter aufgrund anderer Daten)
# alle Werte von age für sex = 1
age[sex == 1]
## [1] 15 32 12 18 22 17 20 21 19
# auch kombinierte Bedingungen sind möglich
# alle Werte von age > 10 und sex = 2
age[sex == 2 & age > 10]
## [1] 17 22 24 34 23 29 15 23

Slicing bei Dataframes

Siehe zur Auswahl von Teilen von Datenobjekten die Units dataframe oder dplyr

Transformationen

Vektorisierung

Datentransformationen nutzen die Eigenschaft von R, automatisch eine Operation auf alle bzw. ausgewählte Elemente eines Objekts anzuwenden.

Bei zweidimensionalen Datenobjekten (Tibbles, DataFrames, Matrizen) muss für Transformationen der jeweils relevante Teil ausgewählt werden. Sind DataFrames in der üblichen Art aufgebaut (Zeilen sind Beobachtungen, Spalten sind Variablen), dann sind Transformationen üblicherweise Operationen, die innerhalb einer Beobachtung gemacht werden, also zeilenweise (waagerecht) passieren. R kann grundsätzlich in beliebiger Richtung transformieren.

Basis für Transformationen im Base-System sind die sog. vectorisierten Operationen

Ein paar Beispiele und ein paar Probleme:

# simple calculator operations
1 + 1
## [1] 2
2 * 5
## [1] 10
9 / 3
## [1] 3
2 ^ 3
## [1] 8
# ... work also on vector objects
# operation is repeated for each element
vv <- c(0,1,2,3,4,5,9,10)
vv + 1
## [1]  1  2  3  4  5  6 10 11
vv * 5
## [1]  0  5 10 15 20 25 45 50
# square a vector
vv^2
## [1]   0   1   4   9  16  25  81 100
# root extraction
sqrt(vv)
## [1] 0.000000 1.000000 1.414214 1.732051 2.000000 2.236068 3.000000 3.162278
# logarithmized vector
log(vv)
## [1]      -Inf 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 2.1972246
## [8] 2.3025851
# if vv would be a vector of ratings 0 ... 10
# we could invert it using
10 - vv
## [1] 10  9  8  7  6  5  1  0
# be aware of effects of using sequences
vv * c(2,4)
## [1]  0  4  4 12  8 20 18 40
# ... that must be multiples
# this throws an error, therefore commented out
# vv * c(1,2,3)

# we can get basic descriptive values on the fly
min(vv)
## [1] 0
max(vv)
## [1] 10
mean(vv)
## [1] 4.25
sd(vv)
## [1] 3.615443
var(vv)
## [1] 13.07143
# get n
length(vv)
## [1] 8
# when working with two dimensional data objects (matrices, data frames, tibbles) we have to select the parts we want to work on
 
# create sample dataframe
ddf <-data.frame(
  subj   = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
  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)
)
write.table(ddf, 'v_grades_mini.txt', row.names=F, quote=F, sep='\t')

ddf <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_grades_mini.txt")

ddf
##   subj grade1 grade2 grade3
## 1    1    1.0    4.0    1.3
## 2    2    2.7    3.0    2.3
## 3    3    3.7    1.3    2.7
## 4    4    1.3    1.3    1.0
## 5    5    1.7    1.0    1.3
## 6    6    1.0    1.3    1.3
## 7    7    3.3    2.7    2.3
## 8    8    4.0    4.0    3.7
## 9    9    3.7    3.3    3.0
# calculate mean grade
# accessing a column returns a vector
mean(ddf$grade1)
## [1] 2.488889
mean(ddf[,2])
## [1] 2.488889
# when we access a line as a whole, we compute nonsense
rowMeans(ddf[2,])
##   2 
## 2.5
mean(as.numeric(ddf[2,]))
## [1] 2.5
# we want to get mean grade of subj 2
mean(as.numeric(ddf[2,2:4]))
## [1] 2.666667
mean(as.numeric(ddf[2,c('grade1', 'grade2', 'grade3')]))
## [1] 2.666667
# accessing a part of the dataframe via slicing and applying a function to it calculates overall results like grand mean
# rowwise calculations f. e. to get calculations per observation will be difficult doing it this way

# to get mean grade for all subjects we need to apply the function mean in an appropriate way - see below for examples for apply()

Zeilenweise oder spaltenweise Operationen mit apply()

Mit der Kombination aus Slicing und apply() können wir gezielte Datenmodifikationen machen.

apply() hat normalerweise 3 Parameter - den Teil-DataFrame, auf den es angewendet werden soll - eine Richtung (1 ist zeilenweise, 2 ist spaltenweise) - eine Funktion, die zur Anwendung kommen soll - ggf. können weitere Argumente für die Funktion angehängt werden

require(tidyverse)
## Loading required package: tidyverse
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
## ✓ tibble  3.1.0     ✓ dplyr   1.0.5
## ✓ tidyr   1.1.3     ✓ stringr 1.4.0
## ✓ readr   1.4.0     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
dd <- read_delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_grades_mini.txt", delim='\t')
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   subj = col_double(),
##   grade1 = col_double(),
##   grade2 = col_double(),
##   grade3 = col_double()
## )
# we would like to know the mean of the grades for every observation
apply(dd[,2:4], 1, mean)
## [1] 2.100000 2.666667 2.566667 1.200000 1.333333 1.200000 2.766667 3.900000
## [9] 3.333333
# we get column means
apply(dd[,2:4], 2, mean)
##   grade1   grade2   grade3 
## 2.488889 2.433333 2.100000
# or robust estimators of column means 
# getting rid of the 20% most extreme values and calculating the mean from the rest of the data
apply(dd[,2:4], 2, mean, trim=0.2)
##   grade1   grade2   grade3 
## 2.485714 2.414286 2.028571

Neue Spalten generieren, an vorhandenen DataFrame anhängen, Spalten löschen, Dataframe löschen

Wir können neue Spalten für einen DataFrame generieren, indem wir einen bisher nicht existierenden Spalennamen verwenden. Wir löschen Spalten (Variablen), indem wir ihnen NULL zuweisen.

Es empfiehlt sich grundsätzlich, Variablen nie zu überschreiben sondern die Ergebnisse einer Modifikation in einer neuen Variable zu speichern. Das erhöht die Transparenz, die Überprüfbarkeit und verringert damit die Fehleranfälligkeit.

# dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_grades_mini.txt")
require(tidyverse)
dd <- read_delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_grades_mini.txt", delim='\t')
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   subj = col_double(),
##   grade1 = col_double(),
##   grade2 = col_double(),
##   grade3 = col_double()
## )
head(dd)
## # A tibble: 6 x 4
##    subj grade1 grade2 grade3
##   <dbl>  <dbl>  <dbl>  <dbl>
## 1     1    1      4      1.3
## 2     2    2.7    3      2.3
## 3     3    3.7    1.3    2.7
## 4     4    1.3    1.3    1  
## 5     5    1.7    1      1.3
## 6     6    1      1.3    1.3
dd$r_means <- NA
head(dd)
## # A tibble: 6 x 5
##    subj grade1 grade2 grade3 r_means
##   <dbl>  <dbl>  <dbl>  <dbl> <lgl>  
## 1     1    1      4      1.3 NA     
## 2     2    2.7    3      2.3 NA     
## 3     3    3.7    1.3    2.7 NA     
## 4     4    1.3    1.3    1   NA     
## 5     5    1.7    1      1.3 NA     
## 6     6    1      1.3    1.3 NA
nrow(dd)
## [1] 9
t_means <- apply(dd[,2:4], 1, mean)
length(t_means)
## [1] 9
dd$r_means <- t_means
head(dd)
## # A tibble: 6 x 5
##    subj grade1 grade2 grade3 r_means
##   <dbl>  <dbl>  <dbl>  <dbl>   <dbl>
## 1     1    1      4      1.3    2.1 
## 2     2    2.7    3      2.3    2.67
## 3     3    3.7    1.3    2.7    2.57
## 4     4    1.3    1.3    1      1.2 
## 5     5    1.7    1      1.3    1.33
## 6     6    1      1.3    1.3    1.2
# we could have done it directly
dd$r_means2 <- apply(dd[,2:4], 1, mean)
head(dd)
## # A tibble: 6 x 6
##    subj grade1 grade2 grade3 r_means r_means2
##   <dbl>  <dbl>  <dbl>  <dbl>   <dbl>    <dbl>
## 1     1    1      4      1.3    2.1      2.1 
## 2     2    2.7    3      2.3    2.67     2.67
## 3     3    3.7    1.3    2.7    2.57     2.57
## 4     4    1.3    1.3    1      1.2      1.2 
## 5     5    1.7    1      1.3    1.33     1.33
## 6     6    1      1.3    1.3    1.2      1.2
# we delete redundant column r_means2
dd$r_means2 <- NULL
head(dd)
## # A tibble: 6 x 5
##    subj grade1 grade2 grade3 r_means
##   <dbl>  <dbl>  <dbl>  <dbl>   <dbl>
## 1     1    1      4      1.3    2.1 
## 2     2    2.7    3      2.3    2.67
## 3     3    3.7    1.3    2.7    2.57
## 4     4    1.3    1.3    1      1.2 
## 5     5    1.7    1      1.3    1.33
## 6     6    1      1.3    1.3    1.2
# we calculate individual grade variances
dd$var <- apply(dd[,2:4], 1, var)
# ... and convert it to sd
dd$sd <- sqrt(dd$var)
# ... and check it against using function sd() in an apply()
dd$sd2 <- apply(dd[,2:4], 1, sd)
head(dd)
## # A tibble: 6 x 8
##    subj grade1 grade2 grade3 r_means   var    sd   sd2
##   <dbl>  <dbl>  <dbl>  <dbl>   <dbl> <dbl> <dbl> <dbl>
## 1     1    1      4      1.3    2.1  2.73  1.65  1.65 
## 2     2    2.7    3      2.3    2.67 0.123 0.351 0.351
## 3     3    3.7    1.3    2.7    2.57 1.45  1.21  1.21 
## 4     4    1.3    1.3    1      1.2  0.03  0.173 0.173
## 5     5    1.7    1      1.3    1.33 0.123 0.351 0.351
## 6     6    1      1.3    1.3    1.2  0.03  0.173 0.173
# we remove column dd$sd2
dd$sd2 <- NULL

# to delete an data object like a data frame we use rm()
# we duplicate dd and store it under the name dd.d
dd.d <- dd
# and now we delete it
rm(dd.d)

Modifikation von Teilen von Dataframes, bedingte Transformationen

Modifikationen an ausgewählten Teilen (Slices) von Dataframes lassen den Rest des Dataframes unverändert.

dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_grades_mini.txt")
head(dd)
##   subj grade1 grade2 grade3
## 1    1    1.0    4.0    1.3
## 2    2    2.7    3.0    2.3
## 3    3    3.7    1.3    2.7
## 4    4    1.3    1.3    1.0
## 5    5    1.7    1.0    1.3
## 6    6    1.0    1.3    1.3
# we seed the random generation to get the same results
set.seed(31)
# we "create" a group column
dd$group <- round(runif(nrow(dd), 1, 2))
# and control the group variable in the first 6 observations
head(dd)
##   subj grade1 grade2 grade3 group
## 1    1    1.0    4.0    1.3     2
## 2    2    2.7    3.0    2.3     2
## 3    3    3.7    1.3    2.7     1
## 4    4    1.3    1.3    1.0     1
## 5    5    1.7    1.0    1.3     2
## 6    6    1.0    1.3    1.3     1
# we calculate the individual observation means of our grades
dd$r_means <- apply(dd[,2:4], 1, mean)
# we create a new column and set it to missing
dd$n_means <- NA
# we modify the mean groupwise and store it in a new column
dd$n_means[dd$group == 1] <- dd$r_means[dd$group == 1] + 0.5
dd$n_means[dd$group == 2] <- dd$r_means[dd$group == 2] - 0.2
head(dd)
##   subj grade1 grade2 grade3 group  r_means  n_means
## 1    1    1.0    4.0    1.3     2 2.100000 1.900000
## 2    2    2.7    3.0    2.3     2 2.666667 2.466667
## 3    3    3.7    1.3    2.7     1 2.566667 3.066667
## 4    4    1.3    1.3    1.0     1 1.200000 1.700000
## 5    5    1.7    1.0    1.3     2 1.333333 1.133333
## 6    6    1.0    1.3    1.3     1 1.200000 1.700000

DataFrame zusammensetzen aus Teilen

Ein Beispiel hierzu findet sich in long_wide

Andere Beispiele hierzu sind zu finden in join

Typ factor() und Reihenfolge der Faktorstufen ‘level’

Eine manchmal irritierende Eigenschaft von Faktoren, d.h. Variablen vom Typ factor() ist, dass die enthaltenen Faktorstufen level eine Ordnung haben. Die Voreinstellung für Faktoren ist, dass die Stufen alphabetisch nach ihren Namen level geordnet sind. Dies bemerkt man u. a. daran, dass die Faktorstufen in dieser Reihenfolge in einer Grafik auftauchen, wenn sie dort verwendet werden. Die Reihenfolge der Faktorstufen kann mit dem Befehl levels() kontrolliert werden. Die numerisch zugewiesenen Werte, die dann beispielsweise in Kontrasten eine Rolle spielen, können über as.numeric(name_of_factor) ausgegeben werden. Hieran sieht man dann die Zuordnung von labels zu Werten. Wenn die Factor-Levels ebenfalls Zahlenwerte (eigentlich Strings mit Ziffern) enthalten, werden diese nicht zu den Stufenwerten, sondern die Faktorstufen-Reihenfolge wird codiert.

Die Reihenfolge kann auch explizit festgelegt werden, um beispielsweise eine Grafik in einer bestimmten Art und Weise auszuführen. (Link)[http://www.cookbook-r.com/Manipulating_data/Changing_the_order_of_levels_of_a_factor/]

Die Reihenfolge der Levels ist eine veränderbare Eigenschaft von Faktoren mit alphabetischer Ordnung als Voreinstellung.

# create a data.frame
ddf <- data.frame(
  subj = c(1,2,3,4,5,6,7,8),
  group = c('nothing', 'moderate', 'little', 'high', 'high', 'nothing', 'moderate', 'little'),
  y = c(0, 5, 3, 8, 9, 1, 4, 2)
  )
# string variables are of type factor by default
class(ddf$group)
## [1] "character"
# printing a factor roports levels in their order. 
# note: default order is alphabetical
ddf$group
## [1] "nothing"  "moderate" "little"   "high"     "high"     "nothing"  "moderate"
## [8] "little"
# levels and their order may be obtained by command levels()
levels(ddf$group)
## NULL
as.numeric(ddf$group)
## Warning: NAs durch Umwandlung erzeugt
## [1] NA NA NA NA NA NA NA NA
# output is organized referring to this order
require(psych)
## Loading required package: psych
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
psych::describeBy(ddf$y, group=ddf$group)
## 
##  Descriptive statistics by group 
## group: high
##    vars n mean   sd median trimmed  mad min max range skew kurtosis  se
## X1    1 2  8.5 0.71    8.5     8.5 0.74   8   9     1    0    -2.75 0.5
## ------------------------------------------------------------ 
## group: little
##    vars n mean   sd median trimmed  mad min max range skew kurtosis  se
## X1    1 2  2.5 0.71    2.5     2.5 0.74   2   3     1    0    -2.75 0.5
## ------------------------------------------------------------ 
## group: moderate
##    vars n mean   sd median trimmed  mad min max range skew kurtosis  se
## X1    1 2  4.5 0.71    4.5     4.5 0.74   4   5     1    0    -2.75 0.5
## ------------------------------------------------------------ 
## group: nothing
##    vars n mean   sd median trimmed  mad min max range skew kurtosis  se
## X1    1 2  0.5 0.71    0.5     0.5 0.74   0   1     1    0    -2.75 0.5
# graphics are also organized like that
boxplot(y ~ group, data=ddf)

# BUT 
# order may be defined in another way
# redefine factor group
ddf$group <- factor(ddf$group, c('nothing', 'little', 'moderate', 'high'))
# check the order
levels(ddf$group)
## [1] "nothing"  "little"   "moderate" "high"
as.numeric(ddf$group)
## [1] 1 3 2 4 4 1 3 2
# affects all the rest, f. e. graphs
boxplot(y ~ group, data=ddf)

Ein anderer Umgang mit Faktoren ist, die Levels numerisch zu definieren, ihnen den Typ factor() zuzuweisen und Labels zu benutzen.

# create a data.frame
ddf <- data.frame(
  subj = c(1,2,3,4,5,6,7,8),
  group = c('nothing', 'moderate', 'little', 'high', 'high', 'nothing', 'moderate', 'little'),
  y = c(0, 5, 3, 8, 9, 1, 4, 2)
  )
# string variables are of type factor by default
class(ddf$group)
## [1] "character"
# note: default order is alphabetical
# if we don't like aphabetical order, we define factor n_group

ddf$o_group <- factor(ddf$group, labels = c("nothing", "little", "moderate", "high"))
ddf$n_group <- as.numeric(ddf$o_group, labels = c("nothing", "little", "moderate", "high"))

levels(ddf$group)
## NULL
levels(ddf$n_group)
## NULL
as.numeric(ddf$group)
## Warning: NAs durch Umwandlung erzeugt
## [1] NA NA NA NA NA NA NA NA
as.numeric(ddf$o_group)
## [1] 4 3 2 1 1 4 3 2
ddf$n_group
## [1] 4 3 2 1 1 4 3 2
ddf$fn_group
## NULL
ddf$group
## [1] "nothing"  "moderate" "little"   "high"     "high"     "nothing"  "moderate"
## [8] "little"
# output is organized referring to this order
require(Rmisc)
## Loading required package: Rmisc
## Loading required package: lattice
## Loading required package: plyr
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
## The following object is masked from 'package:purrr':
## 
##     compact
Rmisc::summarySE(data = ddf, "y", groupvars="group")
##      group N   y        sd  se       ci
## 1     high 2 8.5 0.7071068 0.5 6.353102
## 2   little 2 2.5 0.7071068 0.5 6.353102
## 3 moderate 2 4.5 0.7071068 0.5 6.353102
## 4  nothing 2 0.5 0.7071068 0.5 6.353102
Rmisc::summarySE(data = ddf, "y", groupvars="o_group")
##    o_group N   y        sd  se       ci
## 1  nothing 2 8.5 0.7071068 0.5 6.353102
## 2   little 2 2.5 0.7071068 0.5 6.353102
## 3 moderate 2 4.5 0.7071068 0.5 6.353102
## 4     high 2 0.5 0.7071068 0.5 6.353102
Rmisc::summarySE(data = ddf, "y", groupvars="n_group")
##   n_group N   y        sd  se       ci
## 1       1 2 8.5 0.7071068 0.5 6.353102
## 2       2 2 2.5 0.7071068 0.5 6.353102
## 3       3 2 4.5 0.7071068 0.5 6.353102
## 4       4 2 0.5 0.7071068 0.5 6.353102
# graphics are also organized like that
boxplot(y ~ group, data=ddf)

boxplot(y ~ n_group, data=ddf)

Verwendung eigener Funktionen

Eigene Funktionen können einfach definiert werden

# a vector
vv <- c(3,5,7,3,9)
#using a user defined function
sum.plus.2 <- function(x){
  sum(x) + 2
}

sum.plus.2(vv)
## [1] 29
# function that tests, if value is contained in vector of values
test.for <- function(x, critical){
  is.element(critical, x)
} 

test.for(vv, 7)
## [1] TRUE
# function that tests, whether one of some values is contained in vector of values
test.for.one.of <- function(x, criticals){
  sum(is.element(criticals, x)) > 0
} 

test.for.one.of(vv, c(5,7,37))
## [1] TRUE
test.for.one.of(vv, c(36, 1))
## [1] FALSE
# v <- c('a','b','c','e')
# subv <- c('a', 'f')
# subv %in% v
## returns a vector TRUE FALSE
# is.element(subv, v)
## returns a vector TRUE FALSE

Verwenden eigener Funktionen in apply()

Eigene Funktionen können einfach definiert werden: `function(parameters){commands}

Im Befehl apply() können Funktionen ‘on the fly’ definiert werden.

ddf <-data.frame(
  subj  =c(1,2,3,4,5),
  gender=c('f','m','m','f','f'),
  fun1   =c(10,  8, 7, 9, 3),
  fun2   =c(13,  9, 8, 9, 5),
  fun3   =c( 9, 20, 7, 4, 5))

# get each value squared and divided by 2
apply(ddf[c('fun1', 'fun2', 'fun3')], 1, function(x) (x^2)/2)
##      [,1]  [,2] [,3] [,4] [,5]
## fun1 50.0  32.0 24.5 40.5  4.5
## fun2 84.5  40.5 32.0 40.5 12.5
## fun3 40.5 200.0 24.5  8.0 12.5

Aber auch vorher definierte Funktionen können eingesetzt werden. Diese Funktionen erhalten als ersten Parameter den ausgewählten Slice von apply, weitere können folgen. Hier ein Beispiel, in dem für jede untersuchte Person geschaut werden soll, ob bestimmte, kritische Werte in einer Gruppe von Variablen, z. B. Items, vorkommen.

# create sample dataframe
ddf <-data.frame(
  subj  =c(1,2,3,4,5),
  gender=c('f','m','m','f','f'),
  fun1   =c(10,  8, 7, 9, 3),
  fun2   =c(13,  9, 8, 9, 5),
  fun3   =c( 9, 20, 7, 4, 5))
ddf
##   subj gender fun1 fun2 fun3
## 1    1      f   10   13    9
## 2    2      m    8    9   20
## 3    3      m    7    8    7
## 4    4      f    9    9    4
## 5    5      f    3    5    5
# function that tests, whether one of some values is contained in vector of values (c.f. transformations)
test.for.one.of <- function(x, criticals){
  sum(is.element(criticals, x)) > 0
} 

# find out, which subj has any of the critical values in any of his fun* items
apply(ddf[c('fun1', 'fun2', 'fun3')], 1, test.for.one.of, criticals = c(10, 20))
## [1]  TRUE  TRUE FALSE FALSE FALSE
# get mean of fun1 and fun2 for each observation (subj)
apply(ddf[c('fun1', 'fun2')], 1, mean)
## [1] 11.5  8.5  7.5  9.0  4.0
# get mean of the whole column of fun1 and fun2 
apply(ddf[c('fun1', 'fun2')], 2, mean)
## fun1 fun2 
##  7.4  8.8
# store result in newly generated column in dataframe
# it contains mean of fun1 and fun2 for each subject
ddf$mean_fun <- apply(ddf[c('fun1', 'fun2')], 1, mean)
ddf
##   subj gender fun1 fun2 fun3 mean_fun
## 1    1      f   10   13    9     11.5
## 2    2      m    8    9   20      8.5
## 3    3      m    7    8    7      7.5
## 4    4      f    9    9    4      9.0
## 5    5      f    3    5    5      4.0
# create sample dataframe
ddf <-data.frame(
  subj  =c(1,2,3,4,5),
  gender=c('f','m','m','f','f'),
  fun1   =c(10, 8, 7, 9, 3),
  fun2   =c(13, 9, 8, 9, 5))
ddf
##   subj gender fun1 fun2
## 1    1      f   10   13
## 2    2      m    8    9
## 3    3      m    7    8
## 4    4      f    9    9
## 5    5      f    3    5
# get mean of fun1 and fun2 for each observation (subj)
apply(ddf[c('fun1', 'fun2')], 1, mean)
## [1] 11.5  8.5  7.5  9.0  4.0
# get mean of the whole column of fun1 and fun2 
apply(ddf[c('fun1', 'fun2')], 2, mean)
## fun1 fun2 
##  7.4  8.8
# store result in newly generated column in dataframe
# it contains mean of fun1 and fun2 for each subject
ddf$mean_fun <- apply(ddf[c('fun1', 'fun2')], 1, mean)
ddf
##   subj gender fun1 fun2 mean_fun
## 1    1      f   10   13     11.5
## 2    2      m    8    9      8.5
## 3    3      m    7    8      7.5
## 4    4      f    9    9      9.0
## 5    5      f    3    5      4.0

Eigene Funktionen können auch im Befehl mutate() im Package dplyr() verwendet werden. Das Vorgehen und Beispiele dazu finden sich in der Unit dplyr

Missing Data

Missing Data werden in eigener Unit miss abgehandelt.

Format: wide bzw. long

Dargestellt in einer eigenen Unit unter long_wide.Rmd bzw. long_wide.html

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

Beispiele

Beispiel: Vergleich körperlicher Attraktivität

Vergleich körperlicher Attraktivität

Syntax

In diesem Beispiel wird gezeigt:

  • Datentyp von Variablen kontrollieren
  • Rating-Item invertieren
  • Zugriff auf eine Gruppe von Variablen mittels einer Liste von Variablennamen
  • Anwenden einer Funktion (mean) auf eine Gruppe von Variablen
  • Speichern des Funktionsergebnisses in einer neuen Variablen im DataFrame
  • Generieren einer neuen Variablen durch Verrechnung bestehender Variable
# read data
dfbmi <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_bmi.txt")
# control data type
lapply(dfbmi, class)
## $nr
## [1] "integer"
## 
## $name
## [1] "character"
## 
## $gender
## [1] "integer"
## 
## $height
## [1] "integer"
## 
## $weight
## [1] "integer"
## 
## $grade
## [1] "numeric"
## 
## $c_phys_app
## [1] "integer"
## 
## $c_good_way
## [1] "integer"
## 
## $c_dress
## [1] "integer"
## 
## $c_bad_way
## [1] "integer"
## 
## $c_figure
## [1] "integer"
## 
## $filling_time
## [1] "numeric"
# str(object) is an alternative way to get information on data type
str(dfbmi)
## 'data.frame':    30 obs. of  12 variables:
##  $ nr          : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ name        : chr  "Meier" "Müller" "Strauß" "Übeling" ...
##  $ gender      : int  2 2 1 1 1 1 1 1 1 2 ...
##  $ height      : int  180 176 180 182 160 156 165 160 159 189 ...
##  $ weight      : int  60 54 110 52 62 41 71 70 44 60 ...
##  $ grade       : num  2.02 1 2.03 1 1 1 2.47 2.37 2.26 1.21 ...
##  $ c_phys_app  : int  2 3 5 4 3 3 4 4 4 5 ...
##  $ c_good_way  : int  1 4 5 5 2 4 3 4 3 4 ...
##  $ c_dress     : int  2 3 5 4 2 3 4 4 3 5 ...
##  $ c_bad_way   : int  4 1 1 2 4 3 2 2 2 1 ...
##  $ c_figure    : int  1 5 5 3 1 4 3 4 4 4 ...
##  $ filling_time: num  39.6 26 26 26 26 ...
# invert item comp_bad_way and add it to dataframe
dfbmi["i_c_bad_way"] <- 6 - dfbmi$c_bad_way
# define comp items
c_item_names <- c("c_phys_app", "c_good_way", "c_dress", "i_c_bad_way", "c_figure")
# aggregate comp items to comp scale using apply()
dfbmi["comp"] <- apply(dfbmi[,c_item_names], 1, mean)
# create new variable bmi and add it to the dataframe
dfbmi["bmi"] <- dfbmi$weight / (dfbmi$height / 100) ** 2
dfbmi[1:5,]
##   nr    name gender height weight grade c_phys_app c_good_way c_dress c_bad_way
## 1  1   Meier      2    180     60  2.02          2          1       2         4
## 2  2  Müller      2    176     54  1.00          3          4       3         1
## 3  3  Strauß      1    180    110  2.03          5          5       5         1
## 4  4 Übeling      1    182     52  1.00          4          5       4         2
## 5  5   Ärger      1    160     62  1.00          3          2       2         4
##   c_figure filling_time i_c_bad_way comp      bmi
## 1        1        39.63           2  1.6 18.51852
## 2        5        26.00           5  4.0 17.43285
## 3        5        26.00           5  5.0 33.95062
## 4        3        26.00           4  4.0 15.69859
## 5        1        26.00           2  2.0 24.21875

Bilden neuer Variablen, in der die Gewichtsklassen kodiert werden. Hintergrund für die Techniken ist dataframe.html, hier speziell die Slicing Techniken.

Idee: Bedingte Auswahl der Beobachtungen und generieren je einer Gruppierungsvariable vom Typ factor für die 4 BMI-Klassen (low, normal, high, obese) bzw. eine dichotome Variable (Tpy factor) für Normalgewicht vs Nicht-Normalgewicht. Die neu gebildeten Variariablen sollen in den Dataframe integriert werden.

(Der Chunk oben muss bereits gelaufen sein, d. h. die Variable bmi muss bereits existieren)

# get column bmi of dataframe dfbmi
dfbmi$bmi
##  [1] 18.51852 17.43285 33.95062 15.69859 24.21875 16.84747 26.07897 27.34375
##  [9] 17.40437 16.79684 18.02596 35.26476 26.02305 23.08787 18.71095 17.26354
## [17] 18.64534 17.30612 27.77778 25.53545 28.08901 30.18959 18.93700 22.89307
## [25] 23.37473 16.66667 17.13138 17.78971 15.82609 20.57613
# attach dataframe dfbmi to use column names only
attach(dfbmi)
# get all persons with bmi < 17.5
bmi[bmi < 17.5]
##  [1] 17.43285 15.69859 16.84747 17.40437 16.79684 17.26354 17.30612 16.66667
##  [9] 17.13138 15.82609
# or those with overweight and obese ones
bmi[bmi > 24]
##  [1] 33.95062 24.21875 26.07897 27.34375 35.26476 26.02305 27.77778 25.53545
##  [9] 28.08901 30.18959
bmi[bmi > 30]
## [1] 33.95062 35.26476 30.18959
# create new variable bmi-class and assign values
# create empty vector of same length
bmi_class <- c(1:length(bmi))
bmi_class
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
## [26] 26 27 28 29 30
bmi_class <- c(rep(NA, length(bmi)))    # rep(val, n) creates sequence of n times val
# create it and set all values to NA
# assign values
bmi_class[bmi < 17.5] <- 'low'
bmi_class[bmi > 24] <- 'high'
bmi_class[bmi > 30] <- 'obese'
# show all the not normals
bmi_class
##  [1] NA      "low"   "obese" "low"   "high"  "low"   "high"  "high"  "low"  
## [10] "low"   NA      "obese" "high"  NA      NA      "low"   NA      "low"  
## [19] "high"  "high"  "high"  "obese" NA      NA      NA      "low"   "low"  
## [28] NA      "low"   NA
# set normal weight
bmi_class[bmi >= 17.5 & bmi <= 24] <- 'normal'
# alternative: set all to normal, overwrite the not normal ones
bmi_class2 <- rep('normal', length(bmi))
bmi_class2[bmi < 17.5] <- 'low'
bmi_class2[bmi > 24] <- 'high'
bmi_class2[bmi > 30] <- 'obese'
# same result
bmi_class2
##  [1] "normal" "low"    "obese"  "low"    "high"   "low"    "high"   "high"  
##  [9] "low"    "low"    "normal" "obese"  "high"   "normal" "normal" "low"   
## [17] "normal" "low"    "high"   "high"   "high"   "obese"  "normal" "normal"
## [25] "normal" "low"    "low"    "normal" "low"    "normal"
# create dichotomous variable bmi_normal asl TRUE/FALSE vector
bmi_normal <- rep(NA, length(bmi))
bmi_normal[bmi_class != 'normal'] <- FALSE
bmi_normal[bmi_class == 'normal'] <- TRUE
bmi_normal
##  [1]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
## [13] FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
## [25]  TRUE FALSE FALSE  TRUE FALSE  TRUE
# show bmi and classification
cbind(bmi, bmi_class, bmi_normal)
##       bmi                bmi_class bmi_normal
##  [1,] "18.5185185185185" "normal"  "TRUE"    
##  [2,] "17.4328512396694" "low"     "FALSE"   
##  [3,] "33.9506172839506" "obese"   "FALSE"   
##  [4,] "15.6985871271586" "low"     "FALSE"   
##  [5,] "24.21875"         "high"    "FALSE"   
##  [6,] "16.8474687705457" "low"     "FALSE"   
##  [7,] "26.078971533517"  "high"    "FALSE"   
##  [8,] "27.34375"         "high"    "FALSE"   
##  [9,] "17.4043748269451" "low"     "FALSE"   
## [10,] "16.7968421936676" "low"     "FALSE"   
## [11,] "18.0259573786252" "normal"  "TRUE"    
## [12,] "35.2647569444444" "obese"   "FALSE"   
## [13,] "26.023048986245"  "high"    "FALSE"   
## [14,] "23.0878681306881" "normal"  "TRUE"    
## [15,] "18.7109492465502" "normal"  "TRUE"    
## [16,] "17.2635445362718" "low"     "FALSE"   
## [17,] "18.645344042454"  "normal"  "TRUE"    
## [18,] "17.3061224489796" "low"     "FALSE"   
## [19,] "27.7777777777778" "high"    "FALSE"   
## [20,] "25.5354463915222" "high"    "FALSE"   
## [21,] "28.0890109547143" "high"    "FALSE"   
## [22,] "30.1895906291511" "obese"   "FALSE"   
## [23,] "18.9370029036738" "normal"  "TRUE"    
## [24,] "22.8930740819877" "normal"  "TRUE"    
## [25,] "23.3747260774288" "normal"  "TRUE"    
## [26,] "16.6666666666667" "low"     "FALSE"   
## [27,] "17.1313799621928" "low"     "FALSE"   
## [28,] "17.7897069379857" "normal"  "TRUE"    
## [29,] "15.8260921496611" "low"     "FALSE"   
## [30,] "20.5761316872428" "normal"  "TRUE"
# show bmi of all normals
bmi[bmi_normal]
##  [1] 18.51852 18.02596 23.08787 18.71095 18.64534 18.93700 22.89307 23.37473
##  [9] 17.78971 20.57613
# show bmi of all not normals
bmi[!bmi_normal]
##  [1] 17.43285 33.95062 15.69859 24.21875 16.84747 26.07897 27.34375 17.40437
##  [9] 16.79684 35.26476 26.02305 17.26354 17.30612 27.77778 25.53545 28.08901
## [17] 30.18959 16.66667 17.13138 15.82609
# add new column bmi_class and bmi_normal of type vector to dataframe dfbmi
dfbmi['bmi_class'] <- as.factor(bmi_class)
dfbmi['bmi_normal'] <- as.factor(bmi_normal)
# detach dataframe dfbmi
detach(dfbmi)

Die neu gebildeten BMI-Klassen in einem Boxplot verwenden

# show bmi for bmi_class
boxplot(dfbmi$bmi ~ dfbmi$bmi_class)

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

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.

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

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

Bei der Vergabe von Studienplätzen gibt es das Problem, dass verschiedene Herkunfts-Hochschulen ganz unterschiedliche Benotungskulturen haben. Eine 1.7 der einen Hochschule kann somit eine mittelmäßige Benotung sein, eine 1.3 bei 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 Personen besser vergleichbar macht.

# create sample dataframe
ddf <-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)
)
ddf
##   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

Spannbreite von Reaktionszeiten bei variabler Menge von Reaktionen (Antworten anderer Art z. B. Einschätzungen)

todo: in missings

Individueller Prozentsatz von Missing Values bezogen auf eine Liste von Items

todo: in missings

Hypnotisierbarkeit

todo: in Hypnose Suggestibilitätsindex mit todo: eigene Funktion in apply

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.

Umsetzen von Auswertungsvorgaben: STAI

todo: in missings

Beispiele und Aufgaben

Ein paar Anregungen

PANAS

Ein Beispiel-Datensatz an dem sowohl die Aufbereitung mit dem Base-System, als auch die Aufbereitung mit dplyr bzw. tidyverse demonstriert wird.

Beispiel NEO-FFI

Es gibt ein analoges Beispiel unter dplyr.

Im Datensatz Big5_GEMI_R_recoded.csv finden sich die Daten von 160 Vpn. Von allen haben wir das Alter, das Geschlecht (0=Frau, 1=Mann) sowie 60 NEO-FFI Items. Die zu invertierenden Items sind bereits umkodiert. Die entsprechenden Variablennamen enden auf "_rec" (z. B. neo_ffi_8_rec, neo_ffi_9_rec).

Die Skala Extraversion setzt sich zusammen aus den Variablen:

neo_ffi_2, neo_ffi_7, neo_ffi_12_rec, neo_ffi_17, neo_ffi_22, neo_ffi_27_rec, neo_ffi_32, neo_ffi_37, neo_ffi_42_rec, neo_ffi_47, neo_ffi_52, neo_ffi_57_rec

  1. Wir brauchen einen temporären Dataframe “data_e_t”, der nur die Extraversionsitems enthält

  2. Erstelle einen Dataframe “data_e”, der das Geschlecht, das Alter sowie die Extraversionsitems enthält.

  3. Bilde eine Variable mit Namen “neo_e”, in der der Mittelwert aus den Extraversions-Items gebildet wird und an den Dataframe neo_e angehängt wird.

  4. Gebe aus “data_e” Alter, Geschlecht und die Skalenwerte “neo_e” aller Frauen (vpsex hat Wert 0) aus, die über 24 Jahre alt sind.

  5. Gebe aus “data_e” den Mittelwert von “neo_e” aus, getrennt nach Geschlecht. Normalerweise haben Frauen etwas höhere Extraversions-Werte wie Männer.

require(tibble)
# data <- read_csv2('http://e-scientifics.de/content/datasets/Big5_GEMI_R_recoded.csv') # read data, items already recoded

data <- read.csv2('http://e-scientifics.de/content/datasets/Big5_GEMI_R_recoded.csv') # read data, items already recoded
# require(dplyr)

# solution 1.
data_e_t <- data[,c('neo_ffi_2', 'neo_ffi_7', 'neo_ffi_12_rec', 'neo_ffi_17', 'neo_ffi_22', 'neo_ffi_27_rec', 'neo_ffi_32', 'neo_ffi_37', 'neo_ffi_42_rec', 'neo_ffi_47', 'neo_ffi_52', 'neo_ffi_57_rec')]
# take a look at it
head(data_e_t)
##   neo_ffi_2 neo_ffi_7 neo_ffi_12_rec neo_ffi_17 neo_ffi_22 neo_ffi_27_rec
## 1         1         1              2          1          1              1
## 2         1         0              1          2          1             -2
## 3        -1         1              1          2         -1             -1
## 4         2         1              2          1          0             -1
## 5         1         2              2          2          0             -1
## 6         1         2              2          2          0              1
##   neo_ffi_32 neo_ffi_37 neo_ffi_42_rec neo_ffi_47 neo_ffi_52 neo_ffi_57_rec
## 1          0          1              1          0          0              1
## 2         -1          1              2          1          1              1
## 3          0          1              2          0          0              1
## 4          0          2              1         -1          1              0
## 5          0          2             -1         -2          1              1
## 6          0          2              2          0          2             -1
# solution 2.
data_e <- cbind(data_e_t, data[,c('vpsex', 'vpage')])
# we delete temporary dataframe data_e_t
rm(data_e_t)


# solution 3.
data_e$neo_e <- apply(data_e[,names(data_e)[1:12]], 1, mean)
head(data_e)
##   neo_ffi_2 neo_ffi_7 neo_ffi_12_rec neo_ffi_17 neo_ffi_22 neo_ffi_27_rec
## 1         1         1              2          1          1              1
## 2         1         0              1          2          1             -2
## 3        -1         1              1          2         -1             -1
## 4         2         1              2          1          0             -1
## 5         1         2              2          2          0             -1
## 6         1         2              2          2          0              1
##   neo_ffi_32 neo_ffi_37 neo_ffi_42_rec neo_ffi_47 neo_ffi_52 neo_ffi_57_rec
## 1          0          1              1          0          0              1
## 2         -1          1              2          1          1              1
## 3          0          1              2          0          0              1
## 4          0          2              1         -1          1              0
## 5          0          2             -1         -2          1              1
## 6          0          2              2          0          2             -1
##   vpsex vpage     neo_e
## 1     0    21 0.8333333
## 2     1    33 0.6666667
## 3     0    32 0.4166667
## 4     0    20 0.6666667
## 5     0    28 0.5833333
## 6     0    21 1.0833333
# solution 4.
data_e[data_e$vpsex == 0 & data_e$vpage > 24,]
##     neo_ffi_2 neo_ffi_7 neo_ffi_12_rec neo_ffi_17 neo_ffi_22 neo_ffi_27_rec
## 3          -1         1              1          2         -1             -1
## 5           1         2              2          2          0             -1
## 11          1         2              2          2          0              0
## 26          0         2              2          2          1             -1
## 32          2         1              1          1          1             -1
## 52          1         2              1          1          1              1
## 63         -1         1              1          1          0              0
## 66          1         1              1          2          1             -1
## 87         -1         1             -2          1          0             -1
## 111         2         2              2          2          2              0
## 119        -1         2              2          1         -2             -1
## 126         1         1              2          2          0             -2
## 130        -1         0              2          1         -1              0
## 134        -2         0             -1          0         -1             -1
## 138         1         1              1          1          0              1
## 143         1         0              1          1          1              1
## 160         1        -1              0          1         -1              1
##     neo_ffi_32 neo_ffi_37 neo_ffi_42_rec neo_ffi_47 neo_ffi_52 neo_ffi_57_rec
## 3            0          1              2          0          0              1
## 5            0          2             -1         -2          1              1
## 11           0          2              2          1          1             -1
## 26           1          2              2         -2          2              1
## 32           1          0              1          1          1              1
## 52           1          1              2          1          1              0
## 63           0          1              1          0          1              0
## 66           1          0             -1          2          1             -1
## 87           1          0             -1          0          0              0
## 111          1          2              2         -1          1              0
## 119         -1          2              2          1          0             -1
## 126          0          1              0         -1          1              0
## 130          0          1              0         -2          2             -1
## 134          0          0             -1          1          0             -1
## 138          0          1              1          0          1              0
## 143          0          1              1         -1          1              1
## 160         -1          0              1         -1          0              1
##     vpsex vpage       neo_e
## 3       0    32  0.41666667
## 5       0    28  0.58333333
## 11      0    26  1.00000000
## 26      0    27  1.00000000
## 32      0    46  0.83333333
## 52      0    26  1.08333333
## 63      0    25  0.41666667
## 66      0    25  0.58333333
## 87      0    45 -0.16666667
## 111     0    27  1.25000000
## 119     0    26  0.33333333
## 126     0    25  0.41666667
## 130     0    28  0.08333333
## 134     0    27 -0.50000000
## 138     0    25  0.66666667
## 143     0    29  0.66666667
## 160     0    25  0.08333333
# solution 5.
# we use describeBy of package psych
require(psych)
psych::describeBy(data_e[,c('neo_e')], group=data_e['vpsex'])
## 
##  Descriptive statistics by group 
## vpsex: 0
##    vars  n mean   sd median trimmed  mad   min  max range  skew kurtosis   se
## X1    1 80 0.52 0.48   0.58    0.52 0.37 -0.92 1.58   2.5 -0.22     0.29 0.05
## ------------------------------------------------------------ 
## vpsex: 1
##    vars  n mean   sd median trimmed  mad   min  max range  skew kurtosis   se
## X1    1 80 0.46 0.48    0.5    0.45 0.49 -1.08 1.58  2.67 -0.14     0.22 0.05

Body Comparison (PACS)

html

BMI und Wellbeeing

html

check

  • Slicing Techniken, geschickt kombiniert
  • Zugriff auf Teilstrukturen mittels Bedingungen in Slices
  • Generieren neuer Variablen statt Veränderung bestehender (Reproducability)
  • Wiederholte Modifikationen via apply()
  • Selektion von Beobachtungen via which()
  • Datensätze erweitern um Variablen oder Beobachtungen (cbind, rbind)
  • Datensätze umbauen (long, wide)
  • Zufallsauswahl via sample()

Alternative Tidyverse dplyr()

Version: 11 April, 2021 08:27