Использование dplyr для слияния наборов данных и консолидации столбцов R

У меня есть два набора данных, которые я пытаюсь объединить. Они не являются полными наборами данных, поэтому это означает, что отдельные записи отсутствуют.

Вот data1 (пример — подмножество моих реальных данных):

  squirrel_id   age ageclass trialdate   year   OFT1  MIS1
        10342     1 Y        2008-05-19  2008  0.605 -4.19
        10342     2 A        2009-05-31  2009 -1.85   1.14
        10342     3 A        2010-05-22  2010 -2.39   2.38

Вот data2 (пример — подмножество моих реальных данных):

   squirrel_id focal_age focal_ageclass focal_date focal_yr     PC1     PC2
         10342         1 Y              2008-07-14     2008    0.0932 -2.67  
         10342         3 A              2010-03-13     2010   -2.38    0.216 
         10342         3 A              2010-04-20     2010    0.0203  1.80  

Я пытаюсь сделать две вещи:

  1. объединить эти два набора данных, чтобы я сохранял NA, когда записи неполные (т. Е. data1 имеет 1 запись в age==3, а data2 имеет 2 записи, когда age==3)
  2. объединить столбцы, чтобы сделать набор данных более упорядоченным (т. е. столбцы с разными именами в наборах данных представляют одни и те же вещи: age==focal_age, ageclass==focal_ageclass, trialnumber==focalseq, ageclass==focal_ageclass, year==focal_yr)

Желаемый результат. Я пытаюсь получить окончательный набор данных, который выглядит следующим образом (где для age==3 запись data1 отображается только один раз, а не дважды):

  squirrel_id   age ageclass date       year   OFT1  MIS1   PC1      PC2
        10342     1 Y        2008-05-19 2008  0.605 -4.19   NA       NA 
        10342     1 Y        2008-07-14 2008  NA     NA     0.0932  -2.67
        10342     2 A        2009-05-31 2009 -1.85   1.14   NA       NA
        10342     3 A        2010-05-22 2010 -2.39   2.38   NA       NA    
        10342     3 A        2010-03-13 2010  NA     NA    -2.38    0.216
        10342     3 A        2010-04-20 2010  NA     NA     0.0203  1.80  

Я могу пройти здесь частично, выполнив:

data3<-full_join(data1, data2, 
        by=c("squirrel_id"="squirrel_id", 
                    "year"="focal_yr", 
                     "age"="focal_age", 
                "ageclass"="focal_ageclass"))

но это повторяет значения data1 для age==3 для обеих строк age==3 в data2 (вместо простого сопоставления только первой строки), что дает этот (нежелательный) вывод:

 squirrel_id   age ageclass trialdate   focal_date year   OFT1  MIS1   PC1      PC2
        10342     1 Y        2008-05-19  2008-07-14 2008  0.605 -4.19   0.0932  -2.67 
        10342     2 A        2009-05-31  NA         2009 -1.85   1.14   NA       NA
        10342     3 A        2010-05-22  2010-03-13 2010 -2.39   2.38   -2.38    0.216
        10342     3 A        2010-05-22  2010-04-20 2010 -2.39   2.38    0.0203  1.80  

Обновленный вопрос: Как сделать, чтобы совпадающие записи добавляли NA для всех строк при выполнении full_join? Обратите внимание, что я бы предпочел решение dplyr, так как я не работаю в data.table (например, ответ на этот OP), и я хочу сохранить строки, которые не совпадают (в отличие от этот другой OP).


person Blundering Ecologist    schedule 20.05.2021    source источник


Ответы (1)


Вот data.table подход

пример данных

library(data.table)
data1 <- fread("squirrel_id   age ageclass trialdate   year   OFT1  MIS1
10342     1 Y        2008-05-19  2008  0.605 -4.19
10342     2 A        2009-05-31  2009 -1.85   1.14
10342     3 A        2010-05-22  2010 -2.39   2.38")

data2 <- fread("squirrel_id focal_age focal_ageclass focal_date focal_yr     PC1     PC2
         10342         1 Y              2008-07-14     2008    0.0932 -2.67  
         10342         3 A              2010-03-13     2010   -2.38    0.216 
         10342         3 A              2010-04-20     2010    0.0203  1.80 ")

код

# Assuming the first five columns can be rowbound without problem,
# melt them to long
L <- lapply(list(data1, data2), melt, id.vars = 1:5)

#    squirrel_id age ageclass  trialdate year variable  value
# 1:       10342   1        Y 2008-05-19 2008     OFT1  0.605
# 2:       10342   2        A 2009-05-31 2009     OFT1 -1.850
# 3:       10342   3        A 2010-05-22 2010     OFT1 -2.390
# 4:       10342   1        Y 2008-05-19 2008     MIS1 -4.190
# 5:       10342   2        A 2009-05-31 2009     MIS1  1.140
# 6:       10342   3        A 2010-05-22 2010     MIS1  2.380
# 
# [[2]]
#    squirrel_id focal_age focal_ageclass focal_date focal_yr variable   value
# 1:       10342         1              Y 2008-07-14     2008      PC1  0.0932
# 2:       10342         3              A 2010-03-13     2010      PC1 -2.3800
# 3:       10342         3              A 2010-04-20     2010      PC1  0.0203
# 4:       10342         1              Y 2008-07-14     2008      PC2 -2.6700
# 5:       10342         3              A 2010-03-13     2010      PC2  0.2160
# 6:       10342         3              A 2010-04-20     2010      PC2  1.8000

# Rowbind, ignore columnnames
DT <- data.table::rbindlist(L, use.names = FALSE, fill = FALSE)
#    squirrel_id age ageclass  trialdate year variable   value
# 1:       10342   1        Y 2008-05-19 2008     OFT1  0.6050
# 2:       10342   2        A 2009-05-31 2009     OFT1 -1.8500
# 3:       10342   3        A 2010-05-22 2010     OFT1 -2.3900
# 4:       10342   1        Y 2008-05-19 2008     MIS1 -4.1900
# 5:       10342   2        A 2009-05-31 2009     MIS1  1.1400
# 6:       10342   3        A 2010-05-22 2010     MIS1  2.3800
# 7:       10342   1        Y 2008-07-14 2008      PC1  0.0932
# 8:       10342   3        A 2010-03-13 2010      PC1 -2.3800
# 9:       10342   3        A 2010-04-20 2010      PC1  0.0203
#10:       10342   1        Y 2008-07-14 2008      PC2 -2.6700
#11:       10342   3        A 2010-03-13 2010      PC2  0.2160
#12:       10342   3        A 2010-04-20 2010      PC2  1.8000

# Cast to wide again
dcast(DT, ... ~ variable, value.var = "value")
#    squirrel_id age ageclass  trialdate year   OFT1  MIS1     PC1    PC2
# 1:       10342   1        Y 2008-05-19 2008  0.605 -4.19      NA     NA
# 2:       10342   1        Y 2008-07-14 2008     NA    NA  0.0932 -2.670
# 3:       10342   2        A 2009-05-31 2009 -1.850  1.14      NA     NA
# 4:       10342   3        A 2010-03-13 2010     NA    NA -2.3800  0.216
# 5:       10342   3        A 2010-04-20 2010     NA    NA  0.0203  1.800
# 6:       10342   3        A 2010-05-22 2010 -2.390  2.38      NA     NA
person Wimpel    schedule 20.05.2021
comment
Любая идея, почему R выдает мне Aggregate function missing, defaulting to 'length' как ошибку после того, как я запускаю строку dcast(DT, ... ~ variable, value.var = "value")? - person Blundering Ecologist; 22.05.2021
comment
да .. Это указывает на то, что у вас есть несколько значений в некоторых строках, для OFT/MSI/PC!/PC2... ItDДлина по умолчанию показывает количество значений, которые у вас есть, вместо фактических значений. - person Wimpel; 22.05.2021