Как объединить аккуратные наборы данных и объединить столбцы - PullRequest
1 голос
/ 24 сентября 2019

У меня есть два аккуратных столбика с одним совпадающим ключевым столбцом (ID) и несколько столбцов с одинаковым именем, но с разными значениями строк.Я хотел бы объединить два элемента по идентификатору и добавить дополнительные измерения, временные метки и значения df2 к соответствующим столбцам в df1.

До сих пор я пытался выполнить full_join, merge, left_join и т. Д.:

joined_df <- full_join(df1, df2, by="ID")

Но возвращается столбец с дополнительными столбцами времени, значений и измерений (time.x, value.x и т. Д.).

Однако я хотел бы добавить этидополнительные значения df2 к уже существующим столбцам df1 по идентификатору, чтобы результирующий df добавил строки, но не добавил столбцы.

Вот пример:

df1 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(1,2,3,4,5,6,7,8), 
                  value = c(1, 2, 3, 4, 5, 6, 7, 8)
                  measurement = c(x,s,d,g,u,b,z,e)
                  xy = c(g,h,j,k,t,d,g,t)
df2 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(11,12,13,14,15,16,17,18), 
                  value = c(8, 7, 6, 5, 4, 3, 2, 1),
                  measurement = c(r,t,z,u,i,o,k,f)
                  ab = c(j,k,o,l,p,f,b,c)

Мне нужна функция соединения, которая расширяет столбец ID на количество добавленных строк из df2 и включает дополнительные измерения, значения и временные метки изdf2 в существующие столбцы df1.Ожидаемый результат будет:

df3 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18), 
                  value = c(1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1)
                  measurement = c(x,s,d,g,u,b,z,e,r,t,z,u,i,o,k,f)
                  xy = c(g,h,j,k,t,d,g,t,g,h,j,k,t,d,g,t)
                  ab = c(j,k,o,l,p,f,b,c,j,k,o,l,p,f,b,c))

Каким-то образом я не смог найти что-то.вот так еще.Заранее большое спасибо!

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Мне удалось решить это сейчас, используя комбинацию bind_rows и left_join:

df3 <- bind_rows(df1[,c(2,3,5,6)], df2[,c(1,3,4,5)])

df1_lookup <- 
  df1 %>% select(ID,xy,cv) %>% distinct()

df2_lookup <- 
  df2 %>% select(ID,ab) %>% distinct()

df3 %>% left_join(df1_lookup, by="ID") %>% left_join(df2_lookup, by="ID")

Спасибо!

0 голосов
/ 24 сентября 2019
add_missing_columns <- function(from, to) {
  to[setdiff(names(from), names(to))] <- from[setdiff(names(from), names(to))]
  to
}
df2 <- add_missing_columns(from = df1, to = df2)
df1 <- add_missing_columns(from = df2, to = df1)
res <- rbind(df1, df2)
all.equal(df3, res)
# TRUE

С данными:

df1 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(1,2,3,4,5,6,7,8), 
                  value = c(1, 2, 3, 4, 5, 6, 7, 8),
                  measurement = c(
                     "x", "s", "d", "g", "u", "b", "z", "e"),
                  xy = c(
                     "g", "h", "j", "k", "t", "d", "g", "t"),
                  stringsAsFactors = FALSE)

df2 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(11,12,13,14,15,16,17,18), 
                  value = c(8, 7, 6, 5, 4, 3, 2, 1),
                  measurement = c(
                     "r", "t", "z", "u", "i", "o", "k", "f"),
                  ab = c(
                     "j", "k", "o", "l", "p", "f", "b", "c"),
                  stringsAsFactors = FALSE)

df3 <- data.frame(ID = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4), 
                  time = c(1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18), 
                  value = c(1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1),
                  measurement = c(
                     "x", "s", "d", "g", "u", "b", "z", "e", "r", "t", "z", "u", "i", "o", "k", "f"),
                  xy = c(
                     "g", "h", "j", "k", "t", "d", "g", "t", "g", "h", "j", "k", "t", "d", "g", "t"),
                  ab = c(
                     "j", "k", "o", "l", "p", "f", "b", "c", "j", "k", "o", "l", "p", "f", "b", "c"),
                  stringsAsFactors = FALSE)
...