Ayelavan
Ayelavan

Reputation: 993

avoid for-loop in R

Im sure similar questions have been posted before but none of the answers I haven't been able to find an answer specific to my query.

I have the following code which checks each row in column 2 for the value "STRT" and if the value is not found it copies the value in Column 3 from the above row. Currently this procedure is taking more than 1hr to run as I have a dataset which has more than 300,000 rows.

for (i in 1:nrow(RTable)) {
    if (RTable[i,2] != "STRT") {
        RTable[i,3] <- RTable[i-1,3]
    }
}

Ideally I would like to have a solution that looks something like this

ifelse(RTable$col2 != "STRT", RTable$col3[current row] = RTable$col3[current row -1]

Any help would be appreciated. Thanks in advance for your help!!!

Upvotes: 1

Views: 77

Answers (3)

akrun
akrun

Reputation: 886938

We could use data.table. Convert the 'data.frame' to 'data.table' (setDT(RTable)), create the lag of 'col3' using shift ("col4"), and assign (:=) the values of 'col4' to 'col3' where col2 is not equal to "STRT".

library(data.table)
setDT(RTable)[, col4 := shift(col3)][col2!="STRT", col3 := col4]

Upvotes: 1

adaien
adaien

Reputation: 1932

Create a temporary variable

RTable$col4<-lag(RTable$col3)

Use the ifelse as you wanted

library(dplyr)
RTable %>% mutate(col3=ifelse(col2!="STRT",col3,col4))

Upvotes: 2

cgage1
cgage1

Reputation: 577

Possibly create a fourth column that is your third column shifted, then use your ifelse statement:

a = c(0,0,0,0)                            # just so the column indices match to yours
x = c(1,2,3,4)
y = c(2,3,4,5)
RTable = data.frame(a,x,y)

RTable[,4] = c(0,RTable[-nrow(RTable),3])  # Delete last value in column and add one to the beginning
# ifelse(RTable$col2 != "STRT", RTable$col3, RTable$col4)

I don't know the limitations of your data, but this is an option.

Upvotes: 0

Related Questions