Compare two vectors of different length in R

16,404

Solution 1

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

Solution 2

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

Solution 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"]
Share:
16,404
psoares
Author by

psoares

Updated on June 23, 2022

Comments

  • psoares
    psoares almost 2 years

    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 ..

  • psoares
    psoares over 11 years
    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