2017-08-18 4 views
0

dat1 unten enthalten drei Variablen. Es gibt drei eindeutige IDs, und jede hat mehrere Datensätze. Erstellen Sie eine neue Variable mit einigen Regeln in R

ID <- c(rep(1,7), rep(2,6), rep(3,5)) 
t <- c(seq(1,7), seq(1,6), seq(1,5)) 
y <- c(rep(6,7), rep(1,6), rep(6,5)) 
z <- c(6,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,6,NA,NA,NA,NA) 
randn <- rnorm(18,0,1) 
dat1 <- data.frame(ID, t, y, z, randn) 

bemerken, dass der Wert von z für jede ID ist nicht fehlt, wenn t Minimum (für jede ID die erste Reihe) ist.

Ich muss eine neue Spalte namens NewX erstellen. Beachten Sie, dass jede Zelle im Datenrahmen als Zelle (i, j) ausgedrückt werden kann, wobei i die Nummer der ID und j die Nummer der Aufzeichnung ist. Zum Beispiel ist z (1,1) = 6; z (2,1) = 1 und so weiter.

  • Fall 1: Wenn j = 1 ist (dh der erste Datensatz für jede ID):

    NEWX (i, 1) = rnorm (n = 1, bedeutet = z (i, 1) * randn (i, 1), SD = 1)

  • Fall 2: wenn j> 1 (dh nicht in erster Datensatz für jede ID)

    NEWX (i, j) = rnorm (n = 1 , Mittelwert = randn (i, j) · z (i, j), sd = 1), wobei z (i, j) = z (i, j-1) - NewX (i, j-1)

+3

Ihre Notation ist verwirrend. Sie sollten (i) set.seed verwenden, um ein reproduzierbares Beispiel zu erstellen, und (ii) explizit die Ausgabe anzeigen, die Sie für dieses Beispiel erwarten (zusätzlich zu den Wörtern, die Sie die Regeln dahinter beschreiben). – Frank

+0

Wenn 'NewX' eine Spalte ist, wie könnte sie Zeilen und Spalten haben? Meinst du, es ist ein neuer * Tisch *? – lebelinoz

+0

OP missbraucht Notation, wobei "i" die Gruppe (ID) und "j" die Zeile angibt. Ignoriere alle 'i,' s und denke stattdessen * innerhalb jeder ID ... * Auch im Beispiel von OP sind 'j' und' t' äquivalent. – Gregor

Antwort

2

Ich denke, das funktioniert, wie Sie wollen. Anstatt viele individuelle rnorm Anrufe mit verschiedenen Mitteln zu tun, mache ich eine einzige rnorm mit Mittelwert 0 und addiere die Mittelwert-Anpassung zu jedem.

Zunächst wird eine Funktion zu tun, was Sie zu einer einzigen Gruppe wollen:

foo = function(dat) { 
    NewX = rnorm(nrow(dat)) 
    NewX[1] = NewX[1] + dat$z[1] * dat$randn[1] 
    for (i in 2:nrow(dat)) { 
     dat$z[i] = dat$z[i - 1] - NewX[i - 1] 
     NewX[i] = NewX[i] + dat$randn[i] * dat$z[i] 
    } 
    dat$NewX = NewX 
    return(dat) 
} 

jede Gruppe die Funktion Übernehmen:

# using base: 
do.call(rbind, args = lapply(split(dat1, dat1$ID), foo)) 

# using dplyr 
library(dplyr) 
group_by(dat1, ID) %>% do(foo(.)) 
# # A tibble: 18 x 6 
# # Groups: ID [3] 
#  ID  t  y   z  randn  NewX 
# <dbl> <int> <dbl>  <dbl>  <dbl>  <dbl> 
# 1  1  1  6 6.0000000 0.9613432 7.4952847 
# 2  1  2  6 -1.4952847 -1.3119847 1.8228137 
# 3  1  3  6 -3.3180984 0.4025080 -1.2172146 
# 4  1  4  6 -2.1008838 -1.8188487 5.8479404 
# 5  1  5  6 -7.9488242 0.6298387 -3.5717586 
# 6  1  6  6 -4.3770656 -0.6872249 3.2324739 
# 7  1  7  6 -7.6095394 -0.5542710 2.8111069 
# 8  2  1  1 1.0000000 -0.1773999 -0.7477932 
# 9  2  2  1 1.7477932 -1.8299770 -3.1449473 
# 10  2  3  1 4.8927405 0.2852126 1.8376771 
# 11  2  4  1 3.0550633 -0.5352681 -2.4578430 
# 12  2  5  1 5.5129063 -0.6147433 -3.3131580 
# 13  2  6  1 8.8260643 -0.3065883 0.3074687 
# 14  3  1  6 6.0000000 1.6159438 10.4165718 
# 15  3  2  6 -4.4165718 1.1954419 -6.0555754 
# 16  3  3  6 1.6390036 -1.1659655 -4.3974029 
# 17  3  4  6 6.0364065 0.9377918 6.3873113 
# 18  3  5  6 -0.3509048 -1.1887718 0.6909987 
Verwandte Themen