7

I've been struggling with this problem, and decided to ask for some help after some fails..

Here is my problem, I want to divide these two vectors based on the day, for instance 2012-12-11 will be 3/17 and 2012-12-12 should be 0/7. However I can't seem to figure out how to do this..

> ili

2012-12-11 2012-12-13 2012-12-14 2012-12-17 
     3          6          7          1 
> no.ili

2012-12-11 2012-12-12 2012-12-13 2012-12-14 2012-12-15 2012-12-16 2012-12-17 
    17          7        232        322         38         21         36 

The last attempt was to loop over the two vectors and add the value or zero to a new vector however when I use %in% it doesn't put the values in order (obviously) but if I use == it also doesn't work..

 days.ili <- unique(one.three$timestamp)
 days <- unique(one.week$timestamp)
 ili.vec <- rep(0, length(days))

 for (i in 1:length(days)) {
     if (days.ili[i] %in% days) {
         ili.vec[i] <- ili[i]
     } else {
         ili.vec[i] <- 0
     }
 }

I must be forgetting some thing since I'm not being able to see through this problem.. Can anyone give me any idea about the best way to achieve this in R?

Perhaps an option will be using merge ..

Romain Francois
  • 17,432
  • 3
  • 51
  • 77
psoares
  • 4,733
  • 7
  • 41
  • 55

3 Answers3

12

Something like this:

res <- rep(0, length(no.ili))
where <- match( names(ili), names(no.ili) )
res[ where ] <- ili / no.ili[where]
names(res) <- names(no.ili)
res
# 2012-12-11 2012-12-12 2012-12-13 2012-12-14 2012-12-15 2012-12-16 2012-12-17 
# 0.17647059 0.00000000 0.02586207 0.02173913 0.00000000 0.00000000 0.02777778
Romain Francois
  • 17,432
  • 3
  • 51
  • 77
4

Romain's solution is much cleaner, but assumes no.ili will always be longer..

ili <- 
    c( 3 , 6 , 7 , 1 )
names( ili ) <- 
    as.Date( c( '2012-12-11' , '2012-12-13' , '2012-12-14' , '2012-12-17' ) )

no.ili <- 
    c( 17 , 7 , 232 , 322 , 38 , 21 , 36 )
names( no.ili ) <- 
    as.Date( c( '2012-12-11' , '2012-12-12' , '2012-12-13' , '2012-12-14' , '2012-12-15' , '2012-12-16' , '2012-12-17' ) )


ili.df <- data.frame( ili )
ili.df$Date <- rownames( ili.df )

no.ili.df <- data.frame( no.ili )
no.ili.df$Date <- rownames( no.ili.df )

x <- merge( ili.df , no.ili.df , all = TRUE )

x[ is.na( x ) ] <- 0

result <- x$ili / x$no.ili

names( result ) <- x$Date

result
Anthony Damico
  • 5,779
  • 7
  • 46
  • 77
  • I'm expecting that no.ili should always be longer that ili however if that doesn't happen it is for sure a great way to achieve this – psoares Jan 02 '13 at 12:18
3

Yes, merge is one possible solution. The trick is, to restate the ili/no.ili data frames with their column names as an additional variable, aka long format. Then use merge with the all argument being set to TRUE:

ili2 <- data.frame(date=colnames(ili),                                                                                                                
                   ili=as.numeric(ili[1,]),                                                                                                           
                   stringsAsFactors=FALSE)                                                                                                            
no.ili2 <- data.frame(date=colnames(no.ili),                                                                                                          
                      no.ili=as.numeric(no.ili[1,]),                                                                                                  
                      stringsAsFactors=FALSE)                                                                                                         

tmp <- merge(ili2, no.ili2, all=TRUE)                                                                                                      

Then to execute the division you asked for (and that I initially had overread), first set the missing values to 0, then divide:

tmp[is.na(tmp[,"ili"]),"ili"] <- 0                                                                                                                    
tmp[is.na(tmp[,"no.ili"]),"no.ili"] <- 0                                                                                                              

res <- tmp[,"ili"]/tmp[,"no.ili"]
tophcito
  • 721
  • 5
  • 21