2015-11-05 3 views
1

Каков правильный способ подсчета результата левого внешнего соединения с использованием dplyr?Подсчет результата левого соединения с использованием dplyr

Рассмотрим два фрейма данных:

a <- data.frame(id=c(1, 2, 3, 4)) 
b <- data.frame(id=c(1, 1, 3, 3, 3, 4), ref_id=c('a', 'b', 'c', 'd', 'e', 'f')) 

a определяет четыре различных идентификаторов. b указывает шесть записей, которые содержат идентификаторы в a. Если я хочу, чтобы увидеть, сколько раз упоминается каждый ID, я мог бы попробовать это:

a %>% left_join(b, by='id') %>% group_by(id) %>% summarise(refs=n()) 
Source: local data frame [4 x 2] 

    id refs 
    (dbl) (int) 
1  1  2 
2  2  1 
3  3  3 
4  4  1 

Однако результат может ввести в заблуждение, потому что это означает, что ID 2 сослались один раз, когда на самом деле, он никогда не ссылается (в промежуточный кадр данных, ref_id был NA для ID 2). Я хотел бы избежать введения отдельной библиотеки, такой как sqldf.

+0

Не знаю, почему кто-то хочет downvote этот Q & A ... – Frank

ответ

0

Я с трудом принятия решения, если это хак или правильный способ подсчета ссылок, но это возвращает ожидаемый результат:

a %>% left_join(b, by='id') %>% group_by(id) %>% summarise(refs=sum(!is.na(ref_id))) 
Source: local data frame [4 x 2] 

    id refs 
    (dbl) (int) 
1  1  2 
2  2  0 
3  3  3 
4  4  1 
+3

'tally' это еще один вариант для последнего шага:' a%>% left_join (b, by = 'id')%>% group_by (id)%>% tally (! is.na (ref_id)) ' – Frank

+1

Спасибо @Frank! Я думаю, что 'tally' намного читаем, чем' summaryise', и он остается в 'dplyr'. –

+0

Обратите внимание, что 'tally' не дает нужного имени столбца' refs', тогда как 'summaryize (refs = ...)' does. –

3

С data.table, вы можете сделать

library(data.table) 
setDT(a); setDT(b) 

b[a, .N, on="id", by=.EACHI] 


    id N 
1: 1 2 
2: 2 0 
3: 3 3 
4: 4 1 

Здесь синтаксис x[i, j, on, by=.EACHI].

  • .EACHI относится к каждой строке i=a.
  • j=.N использует специальную переменную для количества строк.
+1

Хорошее использование '.EACHI' – akrun

+0

действительно безумная и xtra аккуратная библиотека. –

1

Есть уже некоторые хорошие ответы, но поскольку вопрос просит не использовать пакеты, это один. Мы выполняем левое соединение на a и b и добавляем столбец refs, который имеет значение ИСТИНА, если ref_id не является NA. Затем с помощью aggregate просуммировать по refs колонки:

m <- transform(merge(a, b, all.x = TRUE), refs = !is.na(ref_id)) 
aggregate(refs ~ id, m, sum) 

даяние:

id refs 
1 1 2 
2 2 0 
3 3 3 
4 4 1 
Смежные вопросы