2013-01-02 13 views
6

mam zmaga się z tym problemem, i postanowił poprosić o pomoc po jakimś zawiedzie ..Porównaj dwa wektory o różnej długości w R

Oto mój problem, chcę podzielić te dwa wektory oparte na dzień, na przykład 2012-12-11 będzie miał wartość 3/17, a 2012-12-12 - 0/7. Jednak nie wydaje się dowiedzieć, jak to zrobić ..

> 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 

Ostatnią próbą było pętli ciągu dwóch wektorów i dodać wartość do zera lub do nowego wektora jednak kiedy używam %in% nie robi” t umieścić wartości w kolejności (oczywiście), ale jeśli mogę użyć == to też nie działa ..

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

muszę być zapominając o pewne rzeczy, ponieważ ja nie będąc w stanie zobaczyć przez ten problem .. czy ktoś daje mi jakiś pomysł na temat najlepszego sposobu na osiągnięcie tego w R?

Być może rozwiązaniem będzie używany merge ..

Odpowiedz

11

coś takiego:

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 
3

Tak, połączenie jest jednym z możliwych rozwiązań. Sztuką jest, aby przekształcić ramki danych ili/no.ili z nazwami kolumn jako dodatkową zmienną, również o długim formacie. Następnie użyj łączyć z wszystkimi argumentem jest ustawiony na 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)                          

następnie wykonać podział ty hasła (i że początkowo miał od akwizycji), najpierw należy ustawić brakujące wartości na 0, a następnie podzielić:

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

res <- tmp[,"ili"]/tmp[,"no.ili"] 
4

Romain rozwiązanie jest znacznie czystsze, ale zakłada no.ili zawsze będzie dłużej ..

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 
+0

Spodziewam się, że no.ili powinno być zawsze dłuższe niż ili, ale jeśli tak się nie stanie, jest to z pewnością świetny sposób na osiągnięcie tego – pavid