Объединение таблиц, которые отсортированы по-разному с R - PullRequest
3 голосов
/ 22 апреля 2011

У меня есть 2 больших стола. Один с идентификаторами (не отсортирован), другой со списком идентификаторов (содержащий все, что в первой таблице) плюс связанные значения для одной переменной. Я хочу добавить столбец в мою первую таблицу, содержащий связанные значения, которые находятся во второй таблице. Есть ли умный способ продолжить, используя реализованные функции R?

т.е.

table 1
id
8979786
62782
6268768
6776566

table 2
id        var
1          5
2          2
3          NA
…
9999999    6

и результат должен быть

table1
id       var
8979786   5
62782     NA
6268768   7
4776566   4

Заранее спасибо

Ответы [ 3 ]

4 голосов
/ 22 апреля 2011

То есть столбец id есть в обеих таблицах?Вы можете merge их вместе: merge(table1, table2, sort = FALSE).Существует множество вариантов слияния, которые позволяют вам эмулировать различные типы объединений, аналогичные внутренним, левым, правым и внешним объединениям в SQL.Я добавил дополнительный параметр sort здесь, чтобы сохранить исходный порядок таблицы 1.

Если в таблице 1 есть идентификаторы, но нет таблицы 2, и вы хотите показать NA для них, добавьте all.x = TRUE в качестве параметра.Это эквивалентно левому соединению.all.y является правым соединением, а all = TRUE эквивалентно полному внешнему соединению.

Воспроизводимый пример:

> set.seed(1)
> table1 <- data.frame( id = sample(1:5, 5, FALSE))
> table1
  id
1  2
2  5
3  4
4  3
5  1
> table2 <- data.frame( id = 1:5, var = rnorm(5))
> table2
  id        var
1  1  1.2724293
2  2  0.4146414
3  3 -1.5399500
4  4 -0.9285670
5  5 -0.2947204
> merge(table1, table2, sort = FALSE)
  id        var
1  2  0.4146414
2  5 -0.2947204
3  4 -0.9285670
4  3 -1.5399500
5  1  1.2724293
3 голосов
/ 17 января 2012

Вот способ data.table сделать это, если данные большие и скорость является проблемой. Для получения дополнительной информации обратитесь к странице справки ?data.table:

Когда я - data.table, x (то есть внешний data.table) должен иметь ключ. я (это внутренний data.table) соединяется с х, используя ключ и соответствующие строки в x возвращаются. Equi-соединение выполняется между каждым столбцом в i к каждому столбцу в ключе x. Матч двоичный поиск в скомпилированном C за O (log n) времени. Если у меня меньше столбцов чем ключ x, то многие строки x могут соответствовать каждой строке i. Если у меня есть больше столбцов, чем ключ X, столбцы я не участвует в присоединиться включены в результат. Если у меня также есть ключ, это ключ, который я столбцы, которые используются, чтобы соответствовать ключевым столбцам x и двоичному слиянию
из двух таблиц.

Обратите внимание, что я немного скорректировал данные выборки, предоставленные Чейзом, чтобы сделать некоторые моменты относительно соответствия в data.table более очевидными:

require(data.table)
#Version 1.7.7
set.seed(1)
table1 <- data.table(id = sample(3:7, 5, FALSE), var1 = rnorm(5), key="id")
table2 <- data.table(id = 5:10, var2 = rnorm(6), key="id")

#Default: If id in table 1 is not in table 2, return NA
table2[table1]
#      id         var2       var1
# [1,]  3           NA -0.2947204
# [2,]  4           NA  1.2724293
# [3,]  5 -0.005767173 -0.9285670
# [4,]  6  2.404653389 -1.5399500
# [5,]  7  0.763593461  0.4146414

#If one wants to get rid of the NAs
table2[table1, nomatch=0]
#      id         var2       var1
# [1,]  5 -0.005767173 -0.9285670
# [2,]  6  2.404653389 -1.5399500
# [3,]  7  0.763593461  0.4146414

#Or the other way around: get all ids of table 2
table1[table2]
#      id       var1         var2
# [1,]  5 -0.9285670 -0.005767173
# [2,]  6 -1.5399500  2.404653389
# [3,]  7  0.4146414  0.763593461
# [4,]  8         NA -0.799009249
# [5,]  9         NA -1.147657009
# [6,] 10         NA -0.289461574

Обязательный тест скорости:

set.seed(10)
df1 <- data.frame(id = sample(1:5e6, 5e6, FALSE))
df2 <- data.frame(id = sample(1:5e6, 5e6, FALSE), var = rnorm(5e6))
system.time(df_solution <- merge(df1, df2, sort = TRUE))
#    user  system elapsed 
#   33.10    0.32   33.54
merge_dt <- function(df1, df2) {
  dt1 <- setkey(as.data.table(df1), "id")
  dt2 <- setkey(as.data.table(df2), "id")
  return(dt1[dt2])
}
system.time(dt_solution <- merge_dt(df1, df2))
#    user  system elapsed 
#   12.94    0.01   12.95 
all.equal(df_solution, as.data.frame(dt_solution))
#[1] TRUE

И мой обычный отказ от ответственности: я еще много узнаю об этом пакете, так что вы можете найти более подробную информацию на домашней странице пакета .

2 голосов
/ 15 января 2012

Я только что реализовал функцию, которая решает эту проблему (объединяя два объекта data.frame, сохраняя порядок для одного из двух объектов), вы можете увидеть код и примеры его использования здесь:

http://www.r -statistics.com / 2012/01 / слияние двух-данные кадра-объекты-то время, сохраняющая-The-строка порядок / * 1 005 *

...