Blog: "Thema: R", deel 6

In deze blog wordt R code gepresenteerd die benut kan worden om een datastructuur te transformeren.
Blog: "Thema: R", deel 6

Stel dat we een dataset hebben van tellingen.  Het generieke model voor dergelijke data is in R een table .  In een relationele database vinden we de bedoelde datastructuur terug indien per rij-entiteit tenminste 2 nominale kenmerken worden vastgelegd in een tabel. Dit worden ook wel categorale data genoemd.

Een dataset met dergelijke gegevens is de waders-set in het R-Package MASS. Het zijn tellingen van waadvogels per vindplaats.

Require(MASS)

Data <- waders

(waders[1:5 , 1: 5])

  S1 S2 S3 S4 S5
A 12 2027 0 0 2070
B 99 2112 9 87 3481
C 197 160 0 4 126
D 0 17 0 3 50
E 77 1948 0 19 310

 

De vindplaatsen zijn de rijen (van A tot O), de kolommen zijn se soorten (S1 tot S19). De waders dataset is bijgevolg een table van vindplaatsXsoort. In een relationele database is de rij-enteit dus een vogel, van iedere vogel worden 2 nominale kenmerken vastgelegd: de soortnaam en de vindplaats.    

Inspectie van deze dataset levert op dat per soort, de tellingen uiteenlopen van 0 tot 40880.  Dit achterhalen we via een combinatie van de functies cl_f (een snelle en zekere variant van apply(x , 2,  f) , fivenum en matrix.

cl_f <- function(x, f) {
r1 <- function(z) f(x[, z])
r2 <- lapply(1:dim(x)[2], r1)
unlist(r2)
}

matrix(cl_f (data,  fivenum),  , 5, byrow = TRUE) 

Minimum  25%  50%  75% Maximum
17 226 745 1987.5 2655
0 0 0 88 1447
0 4 19 66 197
1 88 316 928.5 4330
1 27.5 161 557 1628
0 1 4 39 2063
0 30 90 355 851
0 0 1 59 328
1 18.5 82 418 987
2 21.5 48 212.5 850
1 89 495 1935.5 8336
0 33 76 193.5 7869
0 414 1726 6024 17321
0 6.5 43 2621 6499
0 200 3230 6806 40880
0 0 12 1263 7166
0 0 5 985 7159
0 0 0 276.5

1020

De 19 kolommen van de waders data set zijn in de bovenstaande tabel weergegeven als rijvectoren.

Met behulp van een aantal functies kunnen we deze data overzichtelijker weergeven.

Av berekent het rekenkundig gemiddelde veel sneller dan de mean – functie in R.

av <- function(x) sum(x) / length(x)

De functies B en mb dichotomiseren een matrix op een bepaalde waarde. Nemen we als waarde 10, dan krijgen alle celvullingen >= 10 de waarde 1, celvullingen  < 10 krijgen een 0. We verkrijgen aldus een binaire matrix.

B <- function(vector, value){
bv <- t(t(ceiling(floor(vector / value) / value)))
mb(bv)
}
mb <- function(x) {
x1 <- x / x
x1[is.na(x1)] <- 0
x1
}

De functies MD en MD zijn bedoeld om metadata op te slaan en na functie – executie weer toe te voegen.

MD <- function(x) {
list(rownames(x), colnames(x))
}
MDr <- function(x, y) {
rownames(x) <- c(y[[1]])
colnames(x) <- c(y[[2]])
x
}

 

Functie G bepaalt in een for loop schaalwaarden van verschillende exponenten

G <- function(value,  p, e){
v <- vector()
for(i in (1:p)){
t <- value
v[i] <- i^e * t
}
v
}

De functies E1 en CA leveren respectievelijk een maateenheid en de waarde van de exponent op.

E1 <- function(x) min(cl_f(x, av))
 
CA <- function(data, p) {
r <- E1(data)
s <- seq(from = 0.1, to = 10 , by = 0.1)
f <- function(z) G(r, p, z)[p]
re <- abs(max(data) - unlist(lapply(s, f)))
s[which(re==min(re))]
}

In CaT vinden we alle functies gecoördineerd aan het werk.

CaT <- function(data, p, f = E1) {
na <- MD(data)
r <- f(data)
e <- CA(data, p)
r1 <- G(r, p, e)
r2 <- c(r,r1)
f1 <- function(w) (cl_t (data, function(z, y) B(z, w)))
Li <- lapply(r2, f1)
result <- Reduce('+', Li)
result <- MDr(result, na)
result
}

 

De calibratie van de waders set leverde het volgende op:

De maateenheid was:

E1(waders)
[1] 47.33333

De exponent voor een 10 puntsschaal:

  (CA(waders, 10))
[1] 2.9

De schaalwaarden:

G(E1(waders), 10 , (CA(waders, 10)))

Oude waarde Nieuwe waarde
<47.33 0
47.33 1
353.30 2
1145.03 3
2637.18 4
5037.09 5
8546.84 6
13364.45 7
19684.66 8
27699.40 9
37598.20 10

 

De fivenum tabel laat na transformatie een veel rustiger beeld zien:

(matrix(cl_t(CaT(data, 10), fivenum), ,5 ,byrow = TRUE))

Minimum  25%  50%  75% Maximum
0 0 1 1 2
0 1 2 3 4
0 0 0 1 3
0 0 0 0.5 1
0 1 1 2 4
0 0 1 2 3
0 0 0 0.5 3
0 0 1 1.5 2
0 0 0 0.5 1
0 0 1 1 2
0 1 2 3 5
0 0 1 1 5
0 2 3 4.5 7
0 0 0 3.5 5
0 1 4 5 10
0 0 0 2.5 5
0 0 0 2.5 3
0 0 0 1.5 2

Vanzelfsprekend kan in de functie E1 een andere eenheid worden genomen en kan er gekozen worden voor meer of juist minder schaalwaarden.