2017-02-19 3 views
0

У меня есть следующие данные:Finding частота пар в наборе данных - R

Name Event 

John EventA 
Anna EventA 
Dave EventA 
Stew EventB 
John EventB 
Anna EventB 
John EventC 
Stew EventC 
Dave EventC 

Я хочу, чтобы выяснить, кто те же события больше всего. Так, например, в приведенном выше примере я хочу, чтобы он вернул, что верхние 3 наиболее похожие пары: John & Anna, John & Dave, John & Stew.

Я предполагаю, что я должен был бы сделать матрицу частот, как один ниже

Name John Anna Dave  Stew 
John  0  2  2  2 
Anna  2  0  1  1 
Dave  2  1  0  1 
Stew  2  1  1  0 

А потом превратить его в нечто вроде этого:

Pair   Frequency 

John Anna   2 
John Dave   2 
John Stew   2 
Anna Dave   1 
Anna Stew   1 
Dave Stew   1 

Но я понятия не имею, как идти об этом.

Я работаю с R, поэтому, если кто-нибудь знает способ сделать это, это будет огромной помощью!

+0

В первой таблице, почему запись John-John 0. Почему это не 3? – G5W

+0

Меня интересует только частота других пар. Так что, в то время как Джону - Джону было бы 3, я не хочу этого в моем списке пар. – Mark

ответ

2

Вы можете использовать table базы и melt из reshape2 пакета.

#DATA 
df = structure(list(Name = c("John", "Anna", "Dave", "Stew", "John", 
"Anna", "John", "Stew", "Dave"), Event = c("EventA", "EventA", 
"EventA", "EventB", "EventB", "EventB", "EventC", "EventC", "EventC" 
)), .Names = c("Name", "Event"), row.names = c(NA, -9L), class = "data.frame") 

#Get Pairwise Frequency 
a = table(df) %*% t(table(df))  
a 
#  Name 
#Name Anna Dave John Stew 
# Anna 2 1 2 1 
# Dave 1 2 2 1 
# John 2 2 3 2 
# Stew 1 1 2 2 

#If you want, set diagonal elements to zero (From Karthik's comment) 
#diag(a) <- 0 

library(reshape2) 
output = data.frame(melt(a)) 
colnames(output) = c("Name1", "Name2", "Value") 

#Remove the pair with oneself 
output = output[-(which(output$Name1 == output$Name2)),] 
output 
# Name1 Name2 Value 
#2 Dave Anna  1 
#3 John Anna  2 
#4 Stew Anna  1 
#5 Anna Dave  1 
#7 John Dave  2 
#8 Stew Dave  1 
#9 Anna John  2 
#10 Dave John  2 
#12 Stew John  2 
#13 Anna Stew  1 
#14 Dave Stew  1 
#15 John Stew  2 

#YOU CAN PASTE 'NAME1' and 'NAME2' to a 'PAIR' if necessary 
#output$PAIR = apply(output, 1, function(x) paste(sort(x[1:2]), collapse = " ")) 
+1

'diag (a) <- 0' может установить диагональные записи в ноль. –

+0

Спасибо @ KarthikArumugham, я добавил его к ответу –

1

Это, кажется, немного ближе к тому, что вы просите, и использует только функции в базовом R. Используя «ДФ» от ответа @ децибелах:

x <- as.table(tcrossprod(table(df))) 
x[lower.tri(x, diag = TRUE)] <- NA 
na.omit(data.frame(x)) 
# Name Name.1 Freq 
# 5 Anna Dave 1 
# 9 Anna John 2 
# 10 Dave John 2 
# 13 Anna Stew 1 
# 14 Dave Stew 1 
# 15 John Stew 2 

Использование NA для diag и lower.tri позволяет нам легко удалить значения, которые нас не интересуют.

Смежные вопросы