2017-06-13 4 views
3

I einen Vektor von Indizes haben, die sich wiederholenden Werte enthält:Vectorize Schleife mit sich wiederholenden Indizes

IN <- c(1, 1, 2, 2, 3, 4, 5)  

Ich möchte diese Indizes verwendet zwei Vektoren zu subtrahieren:

ST <- c(0, 0, 0, 0, 0, 0, 0) 
SB <- c(1, 1, 1, 1, 1, 1, 1) 

Allerdings würde Ich mag die Subtraktion in "Ordnung" durchzuführen, so dass nach der Subtraktion der ersten Indexwerte (0,1) die zweite Subtraktion die erste Subtraktion "aufbauen" würde. Ich möchte mit einem Vektor FN, um am Ende die wie folgt aussieht:

c(-2, -2, -1, -1, -1, 0, 0) 

Diese einfach genug ist, in einer for-Schleife zu tun:

for(i in seq_along(IN)){ 
    ST[IN[i]] <- ST[IN[i]] - SB[IN[i]] 
} 

Aber ich brauche diese Schleife laufen oft auf lange Vektoren und das kann viele Stunden dauern. Gibt es eine Möglichkeit, diese Aufgabe zu vektorisieren und eine for-Schleife zu vermeiden? Vielleicht mit einer data.table Technik?

+1

Danke für beide Antworten. Ich werde einige Tests durchführen müssen, um zu sehen, welche Methode für meine Bedürfnisse am schnellsten ist, aber beide erledigen die Aufgabe. – ken

Antwort

4

Sicher, mit data.table, dann ist es

library(data.table) 
DT = data.table(ST) 
mDT = data.table(IN, SB)[, .(sub = sum(SB)), by=.(w = IN)] 
DT[mDT$w, ST := ST - mDT$sub ] 

    ST 
1: -2 
2: -2 
3: -1 
4: -1 
5: -1 
6: 0 
7: 0 

Oder mit Sockel R:

w = sort(unique(IN)) 
ST[w] <- ST[w] - tapply(SB, IN, FUN = sum) 
# [1] -2 -2 -1 -1 -1 0 0 
2

Hier ist eine Option mit aggregate in Basis R:

ag <- aggregate(.~IN, data.frame(IN, ST[IN]-SB[IN]), sum) 
replace(ST, ag[,1], ag[,2]) 

#[1] -2 -2 -1 -1 -1 0 0 

OR mit xtabs:

d <- as.data.frame(xtabs(B~A, data.frame(A=IN, B=ST[IN]-SB[IN]))) 
replace(ST, d[,1], d[,2]) 
Verwandte Themen