2013-01-02 4 views
6

Я боролся с этой проблемой, и решил попросить о помощи после того, как некоторые не удается ..Сравнение двух векторов различной длины в R

Вот моя проблема, я хочу, чтобы разделить эти два вектора, основанные на в день, например, 2012-12-11 будет 3/17, а 2012-12-12 должно быть 0/7. Однако я не могу показаться, чтобы выяснить, как это сделать ..

> 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 

Последняя попытка была перебрать двух векторов и добавить значение или ноль нового вектора однако, когда я использую %in% Безразлично» т положить значения в порядке (очевидно), но если я использую == он также не работает ..

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

Я должен забыть некоторые вещи, так как я не в состоянии видеть через эту проблему .. Может кто-нибудь дает мне представление о наилучшем способе достижения этого в R?

Возможно, вариант будет использовать merge ..

ответ

11

Что-то вроде этого:

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

Да, слияние является одним из возможных решений. Трюк состоит в том, чтобы пересчитать кадры данных ili/no.ili с именами столбцов в качестве дополнительной переменной, так называемый длинный формат. Затем с помощью слияния с все аргументе быть установлен в 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)                          

Затем выполнить разделение вы просили (и что я изначально имел Способность читать), первый набор недостающих значений на 0, а затем разделить:

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

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

решение Romain является гораздо чище, но предполагает no.ili всегда будет больше ..

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

Я ожидаю, что no.ili всегда должен быть длиннее, но если это не произойдет, это, безусловно, отличный способ достичь этого – pavid

Смежные вопросы