Reputation: 1998
# Custom DF
demo <- data.frame(step = seq(1:5), x1 = sample(1:5, 5), x2 = sample(5:9, 5))
# Add column with a result of some operation on subset before this row
demo <- transform(demo, res = 0)
# Fill in "res" with result of operation on several rows (subset) and some coefficients
for (k in 2:nrow(demo)) demo$res[k] <- demo$x1[k] * 2.0 + demo$x1[k - 1] * 3.0
Question : Is it possible to replace loop with "apply" or any other iterator with these conditions
I can simulate index this way :
cycle <- function(k) { k }
lapply(1:nrow(demo), cycle) # use sequence instead of DF itself
This code will print indices from 1 to 5 but how to pass demo as argument into "cycle"?
Upvotes: 0
Views: 68
Reputation: 206616
There's no one-size-fits-all solution to this type of problem. In this particular case you don't need for loops or apply. You can just use vectored operations
demo$res <- c(0,tail(demo$x1,-1)*2 + head(demo$x1,-1)*3)
The dplyr
library has nice lead/lag
functions which can make these operations easier.
library(dplyr)
demo %>% mutate(res2=x1*2 + lag(x1)*3)
# this values the first value as NA rather than 0
It is also possible to pass additional arguments to function in lapply
. For example you can do
cycle <- function(k, d) { paste(k, d[[1]][k]) }
lapply(1:nrow(demo), cycle, demo)
The parameters that are being iterated over are passed as the first parameter, and then you can just include additional parameters in the lapply
call itself and they are passed along to the child function.
Upvotes: 2