Слияние и преобразование двух наборов данных - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть два довольно больших файла данных, которые мне нужно объединить в один, следующим образом:

A  <- tibble(
    id=1:2,
    firstName=c("Alice", "Bob")
)

B  <- tibble(
    id=c(1,1,2),
    email=c("alice@wonder.land.com", "alice2@wonderland.com", "bob@builder.com")
)

desiredResult  <- tibble(
    id=1:2,
    firstName=c("Alice", "Bob"),
    email1=c("alice@wonderland.com", "bob@builder.com"),
    email2=c("alice2@wonderland.com", NA)
) 

Как это можно сделать эффективно?Я пытался использовать spread(), но безуспешно и мог только взломать плохое решение:

notGood  <-
    inner_join(A, B, by = "id") %>%
    split(., .$id) %>%
    map_dfr(function(x) as.tibble(t(unlist(x)))) %>%
    replace(is.na(.), "") %>%
    unite(id, id1, id, sep = "") %>%
    unite(firstName, firstName1, firstName, sep = "") %>%
    unite(email, email1, email, sep = "") %>%
    select(id, firstName, matches("email"))

РЕДАКТИРОВАТЬ:

Предлагаемые решения работают отлично, но как я могу применить их к болеечем один столбец?Как в этом примере:

A  <- tibble(
    id=1:2,
    firstName=c("Alice", "Bob")
)

B  <- tibble(
    id=c(1,1,2),
    email=c("alice@wonder.land.com", "alice2@wonderland.com", "bob@builder.com"),
    phone=c("123", "456", "789")
)

desiredResult  <- tibble(
    id=1:2,
    firstName=c("Alice", "Bob"),
    email1=c("alice@wonderland.com", "bob@builder.com"),
    email2=c("alice2@wonderland.com", NA),
    phone1=c("123", "789"),
    phone2=c("456", NA)
)

Простое добавление дополнительных имен столбцов к предлагаемым ответам не совсем работает:

A %>%
    left_join(B, by='id') %>%
    group_by(id)%>%
    mutate(rn=paste0('email',row_number())) %>%
    mutate(rn2=paste0('phone',row_number())) %>%
    spread(rn, email) %>%
    spread(rn2, phone)

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019
desiredResult <-
  A %>% 
  inner_join(B %>% 
               group_by(id) %>% 
               mutate(ColName = paste0("email",row_number())) %>% 
               ungroup() %>% 
               spread(ColName, email), by = "id")
0 голосов
/ 13 февраля 2019

Проверьте это решение:

B %>%
  group_by(id) %>%
  mutate(rn = paste0('email', row_number())) %>%
  spread(rn, email) %>%
  right_join(A) %>%
  select(id, firstName, everything())

Ответ на добавленный вопрос:

A %>%
  left_join(
    B %>%
      gather(key, val, -id) %>%
      group_by(id, key) %>%
      mutate(key2 = paste0(key, row_number())) %>%
      ungroup() %>%
      select(-key) %>%
      spread(key2, val)
  )
...