2016-05-02 9 views
1

Ich habe den folgenden Code:R double for loop: außen oder anwenden?

a <- c(1,2,2,3,4,5,6) 
b <- c(4,5,6,7,8,8,9) 
data <- data.frame(cbind(a,b)) 
trial <- copy(data) 
for (j in 1: ncol(trial)) { 
    for (i in 2: nrow(trial)) { 
    if (trial[i,j] == trial[i-1,j] & !is.na(trial[i,j]) & !is.na(trial[i-1,j])) { 
    trial[i,j] <- trial[i-1,j] + (0.001*sd(trial[,j], na.rm = T)) 
    } 
} 
} 

Der Code funktioniert perfekt, aber in einem größeren Datenmenge ist ein bisschen langsam. Ich dachte, die Geschwindigkeit zu verbessern, indem Sie entweder die Anwendung oder die äußere Familie verwenden. Die Themen sind:

  1. Ich weiß, wie eine einzelne Schleife angewandt werden soll gelten, aber nicht für 2, besonders in diesem Fall, wo ich einzelne Werte nach fallspezifischen Bedingungen, mit einem anderen einzelnen Wert ersetzen muß (die Verzögerung) sowie ein Multiplikator der Standardabweichung (das etwas, was ich über die gesamte Spalte berechnen müssen, ist,
  2. Außer this solved question, habe ich keine Erfahrung auf allen mit äußeren und vektorisiert Funktionen anstelle von Schleifen
.
+1

Versuchen 'Bibliothek (data.table); f <- function (x) ifelse (x == Verschiebung (x), x + 0,001 * sd (x, na.rm = WAHR), x); setDT (Daten) [, lapply (.SD, f),] ' – Khashaa

+0

@Khashaa kannst du mir ein bisschen von dir Lösung erklären? Ich bin ein Neuling .. die Funktion ist klar, was ist mit dem Rest? [..] und die .SD – Mino

+0

Sie können über data.table hier lernen https://rawgit.com/wiki/Rdatatable/data.table/vignettes/datatable-intro.html – Khashaa

Antwort

1

Mit data.table

library(data.table) 
f <- function(x)ifelse(x==shift(x), x + 0.001* sd(x, na.rm = TRUE), x) 
setDT(data)[, lapply(.SD, f), ] 

Mit dplyr

library(dplyr) 
f <- function(x)ifelse(x==lag(x), x + 0.001* sd(x, na.rm = TRUE), x) 
data %>% 
    mutate_each(funs(f)) 
+0

Ich kann Ihnen nicht den Punkt geben, weil ich weniger als 15 leider bin – Mino

+0

Sorry, ich habe Sie doppelt Code überprüft und es gibt ein Problem: die erste Beobachtung wird zu einem NA – Mino

+0

füge "default" Wert 0 (oder irgendwas anderes) zu "lag" hinzu, wenn du 'dplyr' als' ifelse (x == lag (x, default = 0)) 'verwendest. – Khashaa

0

Funktioniert das für Sie?

a <- c(1,2,2,3,4,5,6) 
b <- c(4,5,6,7,8,8,9) 
data <- data.frame(cbind(a,b)) 
trial <- data.frame(a,b) 
for (j in 1: ncol(trial)) { 
# Finds matching rows and add a single row shift in the results 
# (diff returns n-1 elements and we want n elements) 
    matching<-!c(TRUE, diff(trial[,j])) 
    trial[matching,j]<- data[matching,j]+(0.001*sd(trial[,j], na.rm = T)) 
} 

Ich vektorisiert die innere Schleife, dies sollte eine deutliche Verbesserung der Leistung haben. Ich habe nicht getestet, was mit der SD-Berechnung passieren würde, wenn mehrere übereinstimmende Zeilen vorhanden wären.
Ich werde es anderen überlassen, diese Überarbeitung zu verbessern. Die Verwendung von data.table könnte zusätzliche Vorteile haben.