2015-02-13 5 views
2

У меня есть некоторые данные в этой форме:Создание матрицы соединения из кадра данных в R

> agreers <- read.csv('agreers.csv') 
> attach(agreers) 
> head(agreers) 
     wain1  wain2 count 
1 Founder36 Mnist10_269 673 
2 Founder3 Mnist10_19 665 
3 Mnist10_140 Mnist10_257 663 
4 Founder1 Founder15 659 
5 Founder21 Founder25 654 
6 Founder15 Founder32 654 

Я создал данные таким образом, что wain1 <= wain2, поэтому каждая пара появляется в таблице только один раз. Таким образом, это будет неориентированный граф.

Я хочу, чтобы создать матрицу соединений, например, так:

  Mnist10_269 Mnist10_19 Mnist10_257 . . . 
Founder36 673   ?   ? 
Founder3  ?   665   ? 
Mnist10_140 ?   ?  663 
    . . . 

где 's будет равна нулю, если нет каких-либо данных в agreers?. Так вот что я пытался:

> mat = matrix(0, nrow = length(unique(wain1)), ncol = length(unique(wain2))) 
> rownames(mat) = unique(wain1) 
> colnames(mat) = unique(wain2) 
> for(i in as.integer(rownames(agreers))) mat[wain1[i], wain2[i]] = count[i] 

Это делает что-то, т.е. mat обновляется с номерами, но эти цифры не в нужном месте! Например, я ожидаю, что это вернет 673.

> mat["Founder36","Mnist10_269"] 
[1] 0 

EDIT: Вот немного больше файла данных, чтобы показать «дублированные уровни в факторах» проблемы. Обратите внимание, что Mnist10_140 появляется дважды в первом столбце, но с разными значениями во втором столбце.

wain1,wain2,count 
Founder36,Mnist10_269,673 
Founder3,Mnist10_19,665 
Mnist10_140,Mnist10_257,663 
Founder1,Founder15,659 
Founder21,Founder25,654 
Founder15,Founder32,654 
Mnist10_140,Mnist10_84,643 

При обработке только что подмножество данных, я получаю предупреждения:

> agreers <- read.csv('temp.csv') 
> connections <- xtabs(count ~ factor(wain1, levels = wain1) + factor(wain2, levels = wain2), agreers) 
Warning message: 
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels, : 
    duplicated levels in factors are deprecated 

ответ

4

Если вы хотите базовый R вы можете использовать table

df <- read.table(header=TRUE, text=' wain1  wain2 count 
    Founder36 Mnist10_269 673 
    Founder3 Mnist10_19 665 
Mnist10_140 Mnist10_257 663 
    Founder1 Founder15 659 
    Founder21 Founder25 654 
    Founder15 Founder32 654') 

tab <- with(df,table(factor(wain1, levels=unique(wain1)), 
        factor(wain2, levels=unique(wain2)))) 
tab[which(tab == 1)] = df$count 
tab 

       Mnist10_269 Mnist10_19 Mnist10_257 Founder15 Founder25 Founder32 
    Founder36   673   0   0   0   0   0 
    Founder3    0  665   0   0   0   0 
    Mnist10_140   0   0   663   0   0   0 
    Founder1    0   0   0  659   0   0 
    Founder21    0   0   0   0  654   0 
    Founder15    0   0   0   0   0  654 

EDIT

Как говорит @DavidArenburg, вы можете также использовать xtabs

xtabs(count ~ factor(wain1, levels = unique(wain1)) + factor(wain2, levels = unique(wain2)), df) 
+1

Простой способ - это просто 'xtabs (count ~ factor (wain1, levels = wain1) + factor (wain2, levels = wain2), agreers)' –

+0

С полным набором данных этот подход работает, но дает мне предупреждения о " дублированные уровни в факторах устаревают ». – mhwombat

+0

@mhwombat, добавляя 'unique', должен решить вашу проблему. – cdeterman

1

Посмотрите на пакет reshape2

library(reshape2) 
agreers <- read.table(header = TRUE, stringsAsFactors = FALSE, sep = ',', text = "wain1,wain2,count\nFounder36,Mnist10_269,673\nFounder3,Mnist10_19,665\nMnist10_140,Mnist10_257,663\nFounder1,Founder15,659\nFounder21,Founder25,654\nFounder15,Founder32,654\n") 
conMat <- dcast(agreers, wain1 ~ wain2, fill = 0) 
rownames(conMat) <- conMat$wain1 
conMat$wain1 <- NULL 

conMat["Founder36","Mnist10_269"] 

Это должно решить проблему.

EDIT Это не приводит к сортировке данных. Посмотрите @cdeterman раствор вместо

+0

Я не думаю, что он достигнет желаемого результата ... –

+1

@David Как так? Он не сортируется, как решение cdeterman, но вы все еще можете подмножить и получить правильный ответ. – Lars

+0

Но вы этого не сделали. –

1

Вот вариант подхода @ cdeterman (df от тот же пост)

do.call(table, lapply(df[1:2], function(x) 
      factor(x, levels=unique(x))))*df[,3] 
#    wain2 
# wain1   Mnist10_269 Mnist10_19 Mnist10_257 Founder15 Founder25 Founder32 
# Founder36   673   0   0   0   0   0 
# Founder3    0  665   0   0   0   0 
# Mnist10_140   0   0   663   0   0   0 
# Founder1    0   0   0  659   0   0 
# Founder21    0   0   0   0  654   0 
# Founder15    0   0   0   0   0  654 
Смежные вопросы