Нахождение соответствующих значений на основе двух критериев в R - PullRequest
2 голосов
/ 03 февраля 2020

У меня есть два фрейма данных

df1 <- data.frame(Region = c(1:5), Code = c(10,11,12,15,15), date = c("2018-12","2018-11","2019-01","2019-01","2019-02"))
df2 <- data.frame(Code = c(10,11,12,13,14,15,16,17,18,19),"2018-10" = c(50:59),"2018-11" = c(20:29),"2018-12" = c(25:34),"2019-01" = c(32:41),"2019-01" = c(40:49),"2019-02" = c(40:49))

Я бы хотел сопоставить и сохранить соответствующие значения df1 $ Region в df3.

Результат должен выглядеть следующим образом

df3 <- data.frame(Region = c(1:5),Results=c(25,21,34,45,45))

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Один вариант, включающий dplyr и tidyr, может быть:

df1 %>%
 inner_join(df2 %>%
             pivot_longer(-Code), by = c("Code" = "Code",
                                         "date" = "name"))


  Region Code    date value
1      1   10 2018-12    25
2      2   11 2018-11    21
3      3   12 2019-01    34
4      4   15 2019-01    37
5      5   15 2019-02    45

Я рассмотрел два столбца в df2 с тем же именем, что и опечатка.

1 голос
/ 03 февраля 2020

Мы можем использовать row/column индексирование для извлечения значений путем match, используя столбцы «Код» в качестве индекса строки и «имена дат / столбцов» двух наборов данных, чтобы получить индекс столбца (без использования любые внешние пакеты)

cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code), 
        match(df1$date,
         sub('^X(\\d{4})\\.', "\\1-", names(df2)[-1])))])
#  Region Results
#1      1      25
#2      2      21
#3      3      34
#4      4      37
#5      5      45

ПРИМЕЧАНИЕ. Имена столбцов в записи ОП имели в начале ^X, а его формат был . вместо -, поскольку он был создан с помощью check.names = TRUE ( по умолчанию)


, если наборы данных были созданы с помощью check.names = FALSE, приведенное выше решение может быть дополнительно упрощено

cbind(df1['Region'], Results = df2[-1][cbind(match(df1$Code, df2$Code),
           match(df1$date, names(df2)[-1]))])
#  Region Results
#1      1      25
#2      2      21
#3      3      34
#4      4      37
#5      5      45

Обновление

Если имена столбцов дублируются и хочет найти соответствие на основе этой информации, тогда

i1 <- duplicated(df1$date)
v1 <- numeric(nrow(df1))
v1[!i1] <- df2[-1][cbind(match(df1$Code[!i1], 
             df2$Code),match(df1$date[!i1], names(df2)[-1]))]
v1[i1] <- rev(df2[-1])[cbind(match(df1$Code[i1], 
            df2$Code),match(df1$date[i1], rev(names(df2)[-1])))]
cbind(df1['Region'], Results = v1)
#   Region Results
#1      1      25
#2      2      21
#3      3      34
#4      4      45
#5      5      45

ПРИМЕЧАНИЕ. Внешние пакеты не используются

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...