2017-09-28 28 views
1

J'essaye de préparer des données pour être employées dans diverses applications de visualisation de réseau dans R et également Gephi. Ces formats veulent des identifiants numériques qui relient deux bases de données. J'ai trouvé la dernière partie, mais je ne suis pas en mesure de trouver une manière succincte de créer une variable d'ID numérique à travers les colonnes dans une base de données. Voici un code réplicable qui illustre ce que j'essaie de faire.Comment créer un identifiant d'identifiant unique sur plusieurs colonnes?

org.data <- data.frame(source=c('bob','sue','ann','john','sinbad'), 
     target=c('sinbad','turtledove','Aerosmith','bob','john')) 

desired.data <- data.frame(source=c('1','2','3','4','5'), 
         target=c('5','6','7','1','4')) 


org.data 

    source  target 
1 bob  sinbad 
2 sue  turtledove 
3 ann  Aerosmith 
4 john bob 
5 sinbad john 

desired.data 

    source target 
1 1  5 
2 2  6 
3 3  7 
4 4  1 
5 5  4 

Répondre

4

est ici une méthode de base en utilisant R match sur les noms uniques non cotées dans le data.frame d'origine.

Pour remplacer le data.frame actuel, utilisez

org.data[] <- sapply(org.data, match, table=unique(unlist(org.data))) 

Ici, sapply boucles à travers les variables org.data et applique match à chacun. match renvoie la position du premier argument dans l'argument de la table. Ici, table est les éléments uniques non listés dans org.data: unique(unlist(org.data)). Dans ce cas, sapply renvoie une matrice. Il est converti en un data.frame, en remplaçant l'original par l'ajout de [] à org.data dans org.data[] <-. Cette construction peut être considérée comme préservant la structure de l'objet original pendant l'affectation.

Pour construire une nouvelle data.frame, utilisez

setNames(data.frame(sapply(org.data, match, table=unique(unlist(org.data)))), 
     names(org.data)) 

Ou mieux, comme Henrik suggère, il serait probablement plus facile d'abord créer une copie de la data.frame puis utilisez la première ligne de code pour remplir la copie plutôt que d'utiliser setNames et data.frame.

desired.data <- org.data 

Ces deux retour

source target 
1  1  5 
2  2  6 
3  3  7 
4  4  1 
5  5  4 
+1

Même si OP veut construire une nouvelle trame de données, vous pouvez créer une copie de l'original, puis attribuez-lui le résultat de votre premier code à la copie. 'desired.data <- org.data'; 'desired.data [] <- sapply (org.data, match, table = unique (unlist (org.data)))' (pour vous sauver de 'setNames (data.frame (', parce que nous devons supposer le résultat sera-t-il assigné tôt ou tard de toute façon?). +1! – Henrik

+0

Merci pour la suggestion @Henrik Il serait probablement plus simple de créer une copie d'abord et peut entraîner moins de copies intermédiaires – lmo

+0

Merci, pourriez-vous expliquer, brièvement, ce qui est passe ici? – elliot

3

Vous pouvez essayer ceci:

org.data[] <- as.numeric(factor(c(as.matrix(org.data)), levels = unique(c(as.matrix(org.data))))) 
org.data 
    source target 
1  1  5 
2  2  6 
3  3  7 
4  4  1 
5  5  4 
0

Vous pouvez essayer de suivre. L'idée est de créer des facteurs en utilisant des niveaux sur tous les noms uniques.

library(tidyverse) 
org.data %>% 
    mutate(source2 = factor(source, levels=unique(unlist(org.data)) , labels=1:length(unique(unlist(org.data))))) %>% 
    mutate(target2 = factor(target, levels=unique(unlist(org.data)) , labels=1:length(unique(unlist(org.data))))) 
    source  target source2 target2 
1 bob  sinbad  1  5 
2 sue turtledove  2  6 
3 ann Aerosmith  3  7 
4 john  bob  4  1 
5 sinbad  john  5  4 
0

Convertir en facteurs, puis en entiers.

org.data <- data.frame(source=c('bob','sue','ann','john','sinbad'), 
         target=c('sinbad','turtledove','Aerosmith','bob','john')) 

# need to make sure that columns are characters, not factors 
org.data$source <- as.character(org.data$source) 
org.data$target <- as.character(org.data$target) 

# define possible values that cover the two columns 
levels <- unique(c(org.data$source, org.data$target)) 

# factorize, then cast to integer 
org.data$source <- as.integer(factor(org.data$source, levels=levels)) 
org.data$target <- as.integer(factor(org.data$target, levels=levels)) 

org.data