Säubern von Daten

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

Moderatoren: EDi, jogo

Antworten
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Säubern von Daten

Beitrag von Regression »

Liebes Forum,

ich stehe vor folgendem Problem:
ich habe eine data.table, eine Spalte davon ist eine art Id_Laufvariable. Kleines Beispiel hierzu:

Code: Alles auswählen

data<-data.table(x=c(1,1,1,1,2,2,3,3,4,4,4,4),y=c(1:12))
In diesem Beispiel ist x die von mir genannte Id_Laufvariable.
Nun möchte ich prüfen ob die Id die Länge >2 hat, falls nicht soll der vorherige id_Wert angenommen werden, und erst dann weiter zählen.
D.h. in diesem Beispiel sind die Längen von x=2 und x=3 jeweils zwei.
Nun möchte ich x so bereinigen das letztendlich data folgende Form annimmt:
x<-c(1,1,1,1,1,1,1,1,2,2,2,2)
y<-c(1:12)

wie macht man es am geschicktesten?

Besten Dank im Voraus!
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Säubern von Daten

Beitrag von jogo »

Was soll passieren, wenn gleich die erste Gruppe weniger als 3 Zeilen hat? (Es gibt ja dann keine id einer vorherigen Gruppe.)

Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Säubern von Daten

Beitrag von Regression »

jogo hat geschrieben: Do Apr 12, 2018 2:53 pm Was soll passieren, wenn gleich die erste Gruppe weniger als 3 Zeilen hat? (Es gibt ja dann keine id einer vorherigen Gruppe.)

Gruß, Jörg
Hallo Jörg,

die Id soll immer bei 1 beginnen, dh. auch wenn die erste Gruppe weniger als 3 Zeilen hat, bleibt die Id unverändert...
Ist ein guter Einwand, Danke.

LG
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Säubern von Daten

Beitrag von jogo »

hm, jetzt hatte ich schon angefangen zu programmieren, und habe für diesen speziellen Fall NA gesetzt:

Code: Alles auswählen

DT <- data.table(x=c(1,1,1,1,2,2,3,3,4,4,4,4), y=c(1:12))
DT2 <- DT[, .N, x]

xneu <- function(x, N) { 
  xi <- 1
  if (N[1] < 3) { x[1] <- NA; xi <- 0 }
  
  for (i in 2:length(x)) {
    if (N[i]>2) xi <- xi + 1
    x[i] <- xi
  }
  x
}

DT2[, xneu:=xneu(x, N)]
DT[, xneu:=rep(DT2[,xneu], DT2[, N])][]
insgesamt geht es bestimmt noch hübscher.

Nachtrag (die hübschere Version für die letzte Zeile):

Code: Alles auswählen

DT[, xneu:=DT2[, rep(xneu, N)]][]
2. Nachtrag (die modifizierte Version von xneu() für die von Dir gewünschte Behandlung des speziellen Falls):

Code: Alles auswählen

xneu <- function(x, N) { 
  xi <- 1
  ## if (N[1] < 3) { x[1] <- NA; xi <- 0 }
  
  for (i in 2:length(x)) {
    if (N[i]>2) xi <- xi + 1
    x[i] <- xi
  }
  x
}
Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Säubern von Daten

Beitrag von Regression »

Danke Jörg!

Da ich mit sehr großen Datensätzen arbeiten muss, habe ich mich gefragt, ob ich eventuell auf die Schleife verzichten kann?

LG
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Säubern von Daten

Beitrag von jogo »

Die Schleife wird aber nur auf die Daten des aggregierten Datatables angewandt.
Einen Ansatz habe ich noch parat:
Verwendung von rle(), danach Manipulation des Ergebnisobjektes und anschließend inverse.rle()
Aber wahrscheinlich benötigt die Manipulation des Ergebnisobjektes von rle() genau die gleiche Schleife.

Nachtrag (es geht auch ohne Schleife - zweiter Versuch):

Code: Alles auswählen

library("data.table")
DT <- data.table(x=c(1,1,1,1,2,2,3,3,4,4,4,4), y=c(1:12))
## DT[, x:=c(1,1,2,2,2,3,3,4,4,4,4,4)]  # andere Daten
## DT[, x:=c(1,1,2,2,3,3,3,4,4,4,4,4)]  # andere Daten
DT2 <- DT[, .(lengths=.N), x]
DT2[, values:= DT2[1, lengths<3] +cumsum(lengths>2)][]
DT[, xneu:=inverse.rle(DT2)][] ## oder auch DT[, xneu:=DT2[, rep(values, lengths)]][]
Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Säubern von Daten

Beitrag von Regression »

Das ist toll!
Danke :!:
Antworten