0

How do I replicate one value based on a previous value?

e.g

My dataset

name <- c("sergio",NA,NA,NA,NA,"John", NA,NA,NA,NA,NA,NA)
number <-c(1234,NA,NA,NA,NA,5678, NA,NA,NA,NA,NA,NA) 
mydata <- cbind(as.data.frame(name),as.data.frame(number))

New dataset

name     number
sergio    1234
sergio    1234
sergio    1234
sergio    1234 
John      5678
John      5678 
John      5678 
John      5678
John      5678 
John      5678
....

etc

A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
shasj
  • 85
  • 1
  • 6

2 Answers2

3

You can use na.locf from the "zoo" package:

mydata <- data.frame(
  name = c("sergio",NA,NA,NA,NA,"John", NA,NA,NA,NA,NA,NA),
  number = c(1234,NA,NA,NA,NA,5678, NA,NA,NA,NA,NA,NA))

library(zoo)
na.locf(mydata)
#      name number
# 1  sergio   1234
# 2  sergio   1234
# 3  sergio   1234
# 4  sergio   1234
# 5  sergio   1234
# 6    John   5678
# 7    John   5678
# 8    John   5678
# 9    John   5678
# 10   John   5678
# 11   John   5678
# 12   John   5678

If you prefer to not use a package, here's something that might work:

LOCF <- function(x) {
  A <- cumsum(!is.na(x))
  ave(x, A, FUN = function(x) x[1])
}

mydata[] <- lapply(mydata, LOCF)
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
  • Thaks very much Dear! – shasj Apr 06 '14 at 16:48
  • 2
    @shasj, no problem. Do *consider* up-voting the answer (if it is helpful) and/or [accepting the answer](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) (if it solves your problem). – A5C1D2H2I1M1N2O1R2T1 Apr 06 '14 at 16:56
1

You can also use a simple home-brewed function:

copydown <- function(x) {
   for(iii in seq_along(x)[-1]) if(is.na(x[iii])) x[iii]<- x[iii-1]
   x
}
> copydown(name)
# [1] "sergio" "sergio" "sergio" "sergio" "sergio" "John"   "John"   "John"  
# [9] "John"   "John"   "John"   "John"
mydata[] <- lapply(mydata, copydown)
# notice [] -- so the result will be a data frame rather than a list
lebatsnok
  • 6,329
  • 2
  • 21
  • 22