2015-11-17 12 views
1

У меня есть два dataframes df.o и df.m, как определено ниже. Мне нужно найти, какое наблюдение в df.o (таблица размеров) соответствует тем, какие наблюдения в df.m (таблица фактов) основаны на двух критериях: 1) df.o$Var1==df.o$Var1 и df.o$date1 < df.m$date2 < df.o$date3, так что я получаю правильное значение df.o$oID в df.m$oID (правильное значение вводится вручную df.m$CORRECToID). Мне нужен идентификатор, чтобы завершить слияние потом.Как создать идентификатор (ID) перед слиянием в R?

df.o <- data.frame(oID=1:4, 
        Var1=c("a","a","b","c"), 
        date3=c(2015,2011,2014,2015), 
        date1=c(2013,2009,2012,2013), 
        stringsAsFactors=FALSE) 
df.m <- data.frame(mID=1:3, 
         Var1=c("a","a","b"), 
         date2=c(2014,2010,2013), 
         oID=NA, 
         CORRECToID=c(1,2,3), 
         points=c(5, 10,15), 
         stringsAsFactors=FALSE) 

Я пробовал различные комбинации, как код ниже, но без везения:

df.m$oID[df.m$date2 < df.o$date3 & df.m$date2 > df.o$date1 & df.o$Var1==df.m$Var1] <- df.o$oID 

Я также пробовал экспериментировать с различными комбинациями ifelse, which и match, но никто, кажется, сделать трюк.

Проблема, с которой я сталкиваюсь, заключается в том, что моей заменой было другое количество строк, чем данные, и что «длина длинного объекта не кратна короткой длине объекта».

+0

Есть ли причина, по которой все значения являются символами? Почему дата - это не просто цифры? –

+0

Нет причин в частности. Также могут быть даты. Просто, чтобы сделать это проще, но если это повлияет на решение, я должен, конечно, изменить его ... – dahved

+0

Как 'c (" 2015 "," 2011 "," 2014 "," 2015 ")' проще, чем просто ' (2015,2011,2014,2015) '? –

ответ

2

То, что вы ищете, называется «перекрытие соединения», вы можете попробовать функцию data.table::foverlaps, чтобы достичь этого.

Идея проста

  1. Создайте столбцы накладываться друг на друга (добавить дополнительный столбец df.m)
  2. ключ по этим столбцам
  3. запустить foverlaps и выберите столбец вы хотите назад

    library(data.table) 
    setkey(setDT(df.m)[, date4 := date2], Var1, date2, date4) 
    setkey(setDT(df.o), Var1, date1, date3) 
    foverlaps(df.m, df.o)[, names(df.m), with = FALSE] 
    # mID Var1 date2 oID CORRECToID points date4 
    # 1: 2 a 2010 2   2  10 2010 
    # 2: 1 a 2014 1   1  5 2014 
    # 3: 3 b 2013 3   3  15 2013 
    
+0

Спасибо! Я попробовал это по своим исходным данным, но получил следующее сообщение об ошибке: «Ошибка в if (any (x [[xintervals [2L]]] - x [[xintervals [1L]]] <0L)) stop (" Все записи в столбце ",: отсутствует значение, где требуется TRUE/FALSE' – dahved

+0

У вас, вероятно, есть NA, удалите их и повторите попытку. Вы можете использовать функцию' na.omit', которая имеет аргумент 'col'. –

+0

Я сделал это, но что-то происходит, я не понимаю: перед выполнением 'na.omit' я сделал' nrow (df) ', который возвращался, скажем 1000. Тогда я сделал' sum (is.na (df $ x)) ', который возвращался 0 (что означает, что у меня нет NA, я полагаю). Затем я сделал 'df <- na.omit (df, cols (" x)) 'и после выполнения' nrow (df) 'Теперь я получаю меньшее число , скажем 500. Почему меньше строк? – dahved

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