Reputation: 13
I am having trouble writing a function to replace a for() loop in R.
My data looks like this:
dat1<-rep(sprintf("%02d", 0:52),10)
dat1<-as.data.frame(dat1[40:length(dat1)])
colnames(dat1)<-c("wk")
wk.seas<-c(rep("win",9),rep("spr",13),rep("sum",13),rep("aut",13),rep("win",6))
wks<-sprintf("%02d", 0:53)
This loop produces what I want:
for(j in seq_along(dat1[,1])){
dat1$season[dat1[,1]==wks[j]]<-wk.seas[j]
}#works
I am looking to create a vector in the df with a value for season that corresponds to the week of the year.
Here is my attempt to replicate this loop with a function/lapply combo:
lapply(seq_along(dat1$wk), function(d){
dat1$season[dat1$wk==wks[d]]<-wk.seas[d]
}) #not working
Thank you (edited to add missing code)
Upvotes: 0
Views: 887
Reputation: 150
There are probably a bunch of ways to solve the problem, but two quick solutions come to mind:
Ifelse
:dat1$seas <- ifelse(dat1$wk>=15 & dat1$wk<41, "summer", NA)
dat1[dat1$wk>=15 & dat1$wk<45,2] <- "summer"
You'd want one for each season that you want to designate.
Also, upon creation dat1$wk is being formatted as a factor; I had to pass dat1$wk <- as.numeric(dat1$wk)
in order to be able to do either of the above.
EDIT: +1 for merge/join, if you have the season table elsewhere.
Upvotes: 1
Reputation: 42689
lapply
is the wrong approach. The reason that the lapply
code above doesn't work is because you're modifying an object within a function, which modifies a local copy in the function's environment. Any of the apply
functions will capture the return value and aggregate that; you should not rely on function side-effects.
You're really performing a merge here. Use merge
:
wk <- data.frame(wk=wks, season=wk.seas)
merge(wk, dat1)
Upvotes: 4