質問

I was working with tennis ranking data and noticed that for some dates there is no data. However, I wanted to fill in with the data from previous week.

consider a data structure

structure(list(date2 = structure(c(16076, 16076, 16076, 16076, 
16076, 16076, 16076, 16076, 16076, 16076, 16083, 16083, 16083, 
16083, 16083, 16083, 16083, 16083, 16083, 16083, 16090, 16097, 
16097, 16097, 16097, 16097, 16097, 16097, 16097, 16097, 16097
), class = "Date"), rank = c(5L, 6L, 4L, 3L, 7L, 8L, 2L, 9L, 
10L, 1L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, NA, 7L, 8L, 
9L, 10L, 4L, 5L, 6L, 1L, 2L, 3L), Name = c("Del Potro,Juan Martin", 
"Federer,Roger", "Murray,Andy", "Ferrer,David", "Berdych,Tomas", 
"Wawrinka,Stanislas", "Djokovic,Novak", "Gasquet,Richard", "Tsonga,Jo-Wilfried", 
"Nadal,Rafael", "Del Potro,Juan Martin", "Federer,Roger", "Berdych,Tomas", 
"Wawrinka,Stanislas", "Gasquet,Richard", "Tsonga,Jo-Wilfried", 
"Nadal,Rafael", "Djokovic,Novak", "Ferrer,David", "Murray,Andy", 
NA, "Berdych,Tomas", "Federer,Roger", "Gasquet,Richard", "Tsonga,Jo-Wilfried", 
"Del Potro,Juan Martin", "Ferrer,David", "Murray,Andy", "Nadal,Rafael", 
"Djokovic,Novak", "Wawrinka,Stanislas"), points = c(5255L, 4355L, 
5560L, 5800L, 4180L, 3890L, 12260L, 3140L, 3065L, 13130L, 5415L, 
4355L, 4180L, 3890L, 3140L, 3065L, 13130L, 12260L, 5640L, 5560L, 
NA, 4540L, 4355L, 3050L, 2885L, 5370L, 5280L, 4720L, 14330L, 
10620L, 5710L)), .Names = c("date2", "rank", "Name", "points"
), class = "data.frame", row.names = c(722066L, 722067L, 722078L, 
722106L, 722110L, 722111L, 722118L, 722139L, 722140L, 722143L, 
722330L, 722331L, 722332L, 722333L, 722334L, 722335L, 722406L, 
722407L, 722408L, 722409L, 722672L, 722677L, 722683L, 722684L, 
722689L, 722748L, 722749L, 722750L, 723098L, 723099L, 723100L))

I used this approach to fill,

nadates<-temp85[which(is.na(temp85$rank)),"date2"]
fillindates=as.Date(nadates)-7
nadatesfilled=temp85[temp85$date2 %in% fillindates,]
nadatesfilled$date2<-as.Date(nadatesfilled$date2)+7
temp85filled<-rbind(na.omit(temp85),nadatesfilled)

It worked, however, my question is, is there any better way? Specially, considering in some cases where I have 2,3 weeks missing subsequently (not in this subset of data). I repeated the code to fill in those, but still, any better way?

役に立ちましたか?

解決

library("zoo")
temp85filled <- do.call(rbind, 
        lapply(na.omit(unique(temp85$rank)), function(rank) {
           na.locf(temp85[(is.na(temp85$rank) | temp85$rank == rank),])
}))

Bit trickier than it looks at first because there is a single row with a date that should be replaced with a whole set of rows corresponding to the previous date. To get around that, I did it for each rank separately, but for each rank, looked at that rank or a missing rank (which is why this is not a simple split-apply-combine problem). Within that, na.locf can be used to fill in the missing values (this does assume that the data is sorted by time first; if it is not, that can be done before passing it to na.locf within the lapply anonymous function). temp85fillled is not sorted by date, but it can be. (temp85filled <- temp85filled[order(temp85filled$date2),]).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top