2016-09-21 17 views
0

Ich bin neu in diesem, aber ich bin mir ziemlich sicher, dass diese Frage nicht beantwortet wurde, oder ich bin einfach nicht gut bei der Suche ....Math-Funktion unter Verwendung mehrerer Kriterien

Ich möchte Subtrahieren Sie die Werte in mehreren Zeilen von einer bestimmten Zeile basierend auf übereinstimmenden Spalten und Werten. Meine tatsächlichen Daten werden eine große Matrix mit> 5000 Spalten sein, die jeweils von einem leeren Wert subtrahiert werden müssen, der mit einem Wert in einer Faktorspalte übereinstimmt.

Hier ist eine Beispiel-Datentabelle:

 c1 c2 c3 c4 c5 
    r1 A 1 2 3 aa 
    r2 B 2 3 4 bb 
    r3 C 3 4 5 aa 
    r4 D 4 1 6 bb 
    r5 Blank 2 3 4 aa 
    r6 Blank 3 4 5 bb 

Ich mag die c2, c3 und c4 Werte von C1 = "Blank" Reihe von A, B und C unter Verwendung des c5 Faktors subtrahieren, um Definieren Sie, welche Leerwerte verwendet werden (aa oder bb). Ich möchte, dass die "Blank" -Werte von allen Zeilen subtrahiert werden, die c5-Informationen teilen. (Ich weiß, das zu beschreiben ist verwirrend)

So die Ergebnisse wie folgt aussehen würde:

 c1 c2 c3 c4 c5 
    r1 A -1 -1 -1 aa 
    r2 B -1 -1 -1 bb 
    r3 C 1 1 1 aa 
    r4 D 1 -3 1 bb 

ich die ddply Funktion der Arbeit gesehen habe mit einer einzigen Spalte so etwas wie dies zu tun, aber ich wasn kann das erweitern, um diese Aufgabe für mehrere Spalten auszuführen. Ich bin ein Noob obwohl ...

Vielen Dank für Ihre Hilfe!

Antwort

1

Dies wird für alle möglichen Fälle nicht getestet, aber sollte Ihnen eine Idee geben:

df <- read.table(text = 
"c1 c2 c3 c4 c5 
r1 A 1 2 3 aa 
r2 B 2 3 4 bb 
r3 C 3 4 5 aa 
r4 D 4 1 6 bb 
r5 Blank 2 3 4 aa 
r6 Blank 3 4 5 bb", header = T) 

library(data.table) 
# separate dataset into two 
dt <- data.table(df, key = "c5") 
dt.blank <- dt[c1 == "Blank"] 
dt <- dt[c1 != "Blank"] 

# merge into resulting dataset 
dt.res <- dt[dt.blank] 

# update each column 
columns.count <- ncol(dt) 
for(i in 2:(columns.count-1)) { 
    dt.res[[i]] <- dt.res[[i]] - dt.res[[i + columns.count]] 
} 

# > dt.res 
# c1 c2 c3 c4 c5 i.c1 i.c2 i.c3 i.c4 
# 1: A -1 -1 -1 aa Blank 2 3 4 
# 2: C 1 1 1 aa Blank 2 3 4 
# 3: B -1 -1 -1 bb Blank 3 4 5 
# 4: D 1 -3 1 bb Blank 3 4 5 
+0

Ich konvertierte zurück zu einem data.frame (_dt.res2 <- data.frame (dt.res) _), also konnte ich die "i" Spalten entfernen . Danke Bulat! – Alex

0

Teilen Sie zuerst Ihre Daten, da es keinen Grund gibt, warum Sie sie in einer einzelnen Datenstruktur haben. Dann wenden Sie die Funktion an:

# recreate your data 
df <- data.frame(rbind(c(1:3, "aa"), c(2:4, "bb"), c(3:5, "aa"), c(4,1,6, "bb"), c(2:4, "aa"), c(3:5, "bb"))) 
df[,1:3] <- apply(df[,1:3], 2, as.integer) 

# split it 
blank1 <- df[5,] 
blank2 <- df[6,] 
df <- df[1:4,] 

for (i in 1:nrow(df)) { 
    if (df[i,4] == "aa") {df[i,1:3] <- df[i,1:3] - blank1[1:3]} 
    else     {df[i,1:3] <- df[i,1:3] - blank2[1:3]} 
} 

Es gibt ein paar verschiedene war die Schleife zu laufen, einschließlich Vektorisierung. Aber das reicht aus. Ich würde auch argumentieren, dass es keinen Grund gibt, die Bezeichnungen "aa" und "bb" in der ursprünglichen Datenstruktur zu behalten, was dies einfacher machen würde; aber es ist deine Entscheidung.

+0

Danke für die schnelle Antwort Alex! Der Grund, warum ich die aa bb habe, ist, weil mein aktueller Datensatz viele verschiedene Ebenen hat, für die ich diese Aufgabe gerne ausführen würde. Ich habe darüber nachgedacht, alle Blanks von den anderen Reihen zu trennen, aber es wäre großartig, wenn ich nicht jedes Match einzeln codieren müsste ... – Alex

+0

@Alex Ihr Kommentar klärt Ihre Frage nicht klar für mich. Die Implementierung einer allgemeineren Suchstrategie ist sicherlich einfach. aber Sie müssen eine klare Frage in Ihrem OP stellen. –

+0

Tut mir leid, Alex, ich hatte Probleme, mein Problem zu beschreiben ... – Alex

Verwandte Themen