NETWORK Procedure

Example 2.15 Pattern Matching in a Social Network

This example considers a portion of a social network that conveys relationships between people (friends), residences (lives in), and preferences for particular restaurants (likes). The network, directed graph G, is shown in Figure 232.

Figure 232: Social Network G

Social Network


The following data provide a snapshot of the social connections between Matt and a few of his friends:

data mylib.NodesSocial;
   infile datalines dsd;
   length node $40. type $40. subtype $20.;
   input node $ type $ subtype $;
   label=node;
   datalines;
Matt,               Person,
Rob,                Person,
Chuck,              Person,
Stephen,            Person,
Manoj,              Person,
Bryan,              Person,
Jack,               Person,
Natalia,            Person,
Raleigh,            City,
Philadelphia,       City,
Charlotte,          City,
The Pit Authentic,  Restaurant, BBQ
Red Hot Blue,       Restaurant, BBQ
JimmyJs,            Restaurant, BBQ
Second Empire,      Restaurant, American
Cafe Luna,          Restaurant, Italian
Vivo Rist,          Restaurant, Italian
Moonlight,          Restaurant, Italian
Dumplings,          Restaurant, Chinese
;
data mylib.LinksSocial;
   infile datalines dsd;
   length from $40. to $40. connection $20.;
   input from $ to $ connection $ rating;
   datalines;
Matt,    Rob,               friends,  .
Rob,     Matt,              friends,  .
Matt,    Chuck,             friends,  .
Chuck,   Matt,              friends,  .
Chuck,   Rob,               friends,  .
Rob,     Chuck,             friends,  .
Jack,    Rob,               friends,  .
Rob,     Jack,              friends,  .
Matt,    Stephen,           friends,  .
Stephen, Matt,              friends,  .
Matt,    Manoj,             friends,  .
Manoj,   Matt,              friends,  .
Matt,    Bryan,             friends,  .
Bryan,   Matt,              friends,  .
Matt,    Jack,              friends,  .
Jack,    Matt,              friends,  .
Natalia, Jack,              friends,  .
Jack,    Natalia,           friends,  .
Matt,    Philadelphia,      lives in, .
Stephen, Philadelphia,      lives in, .
Stephen, JimmyJs,           likes,    7
Stephen, Cafe Luna,         likes,    8
Rob,     Raleigh,           lives in, .
Chuck,   Raleigh,           lives in, .
Manoj,   Raleigh,           lives in, .
Jack,    Raleigh,           lives in, .
Natalia, Raleigh,           lives in, .
Bryan,   Charlotte,         lives in, .
Rob,     The Pit Authentic, likes,    7
Jack,    Red Hot Blue,      likes,    9
Chuck,   The Pit Authentic, likes,    8
Chuck,   Cafe Luna,         likes,    6
Chuck,   Second Empire,     likes,    7
Jack,    Vivo Rist,         likes,    8
Manoj,   Dumplings,         likes,    6
Natalia, Red Hot Blue,      likes,    9
Bryan,   Red Hot Blue,      likes,    9
Bryan,   Vivo Rist,         likes,    6
Rob,     Moonlight,         likes,   10
;

The nodes in the nodes data table mylib.NodesSocial represent people, cities, and restaurants. The node attribute type defines the node type. In the case of a restaurant, the node attribute subtype defines the type of restaurant.

The links in the links data table mylib.LinksSocial represent connections between the nodes. The type of connection is defined by the link attribute connection, and in the case of people connected to restaurants, the link attribute rating specifies a rating on a scale of 1 to 10.

For these data, a typical social network pattern search might be to find "friends of Matt who like barbecue restaurants." This pattern is shown in Figure 233.

Figure 233: Query Graph Q

Query Graph


In order to construct this pattern, the query graph can be represented using the data that are created by the following DATA steps:

data mylib.NodesSocialQuery;
   infile datalines dsd;
   length node $40. label $40. type $40. subtype $20.;
   input node $ label $ type $ subtype $;
   datalines;
Matt, Matt, Person,
X,,         Person,
BBQ,,       Restaurant, BBQ
;
data mylib.LinksSocialQuery;
   infile datalines dsd;
   length from $40. to $40. connection $20.;
   input from $ to $ connection $;
   datalines;
Matt, X,    friends
X,    Matt, friends
X,    BBQ,  likes
;

The query graph nodes data table implies that:

  • The query node Matt must be a person with the node attribute label=Matt.

  • The query node X can be any person.

  • The query node BBQ must be a barbecue restaurant (that is, type=Restaurant and subtype=BBQ).

The query graph links data table implies that:

  • Person Matt and person X must be friends.

  • Person X must like the restaurant that is assigned to node BBQ.

You can use the following statements to find all subgraphs that have the specified pattern:

proc network
   direction        = directed
   nodes            = mylib.NodesSocial
   links            = mylib.LinksSocial
   nodesQuery       = mylib.NodesSocialQuery
   linksQuery       = mylib.LinksSocialQuery;
   nodesVar
      vars          = (label type subtype);
   linksVar
      vars          = (connection);
   nodesQueryVar
      vars          = (label type subtype);
   linksQueryVar
      vars          = (connection);
   patternMatch
      outMatchNodes = mylib.OutMatchNodes
      outMatchLinks = mylib.OutMatchLinks;
run;
%put &_NETWORK_;

The progress of the procedure is shown in Output 2.15.1.

Output 2.15.1: PROC NETWORK Log: Pattern Matching in a Social Network

NOTE: ------------------------------------------------------------------------------------------
NOTE: Running NETWORK.                                                                          
NOTE: ------------------------------------------------------------------------------------------
NOTE: The number of nodes in the input graph is 19.                                             
NOTE: The number of links in the input graph is 39.                                             
NOTE: The number of nodes in the query graph is 3.                                              
NOTE: The number of links in the query graph is 3.                                              
NOTE: Processing the pattern matching query using 16 threads across 1 machines.                 
NOTE: The algorithm found 5 matches.                                                            
NOTE: Processing the pattern matching query used 0.00 (cpu: 0.00) seconds.                      
NOTE: The Cloud Analytic Services server processed the request in 0.657603 seconds.             
NOTE: The data set MYLIB.OUTMATCHNODES has 15 observations and 6 variables.                     
NOTE: The data set MYLIB.OUTMATCHLINKS has 15 observations and 4 variables.                     
STATUS=OK  PROBLEM_TYPE=PATTERNMATCH  SOLUTION_STATUS=OK  NUM_MATCHES=5  CPU_TIME=2.49          
REAL_TIME=0.66                                                                                  


Output 2.15.2 displays the output data table mylib.OutMatchNodes, which shows the mappings from nodes in the query graph to nodes in the input graph for each match. For this query, five friends (X) match the specified criteria: Bryan, Chuck, Jack, Rob, and Stephen.

Output 2.15.2: Node Mappings for Friends Who Like Barbecue

matchnodeQnodelabeltypesubtype
1BBQRed Hot BlueRed Hot BlueRestaurantBBQ
1MattMattMattPerson 
1XBryanBryanPerson 
2BBQThe Pit AuthenticThe Pit AuthenticRestaurantBBQ
2MattMattMattPerson 
2XChuckChuckPerson 
3BBQRed Hot BlueRed Hot BlueRestaurantBBQ
3MattMattMattPerson 
3XJackJackPerson 
4BBQThe Pit AuthenticThe Pit AuthenticRestaurantBBQ
4MattMattMattPerson 
4XRobRobPerson 
5BBQJimmyJsJimmyJsRestaurantBBQ
5MattMattMattPerson 
5XStephenStephenPerson 


Output 2.15.3 displays the output data table mylib.OutMatchLinks, which shows the subgraphs for each match.

Output 2.15.3: Subgraphs for Friends Who Like Barbecue

matchfromtoconnection
1BryanMattfriends
1BryanRed Hot Bluelikes
1MattBryanfriends
2ChuckMattfriends
2ChuckThe Pit Authenticlikes
2MattChuckfriends
3JackMattfriends
3JackRed Hot Bluelikes
3MattJackfriends
4MattRobfriends
4RobMattfriends
4RobThe Pit Authenticlikes
5MattStephenfriends
5StephenJimmyJslikes
5StephenMattfriends


Another example search pattern that you might want to find is "friends of Matt who like barbecue restaurants and live in Raleigh." This pattern is shown in Figure 234.

Figure 234: Query Graph Q

Query Graph


In order to construct this pattern, the query graph can be represented using the data that are created by the following DATA steps and the same call to PROC NETWORK as before:

data mylib.NodesSocialQuery;
   infile datalines dsd;
   length node $40. label $40. type $40. subtype $20.;
   input node $ label $ type $ subtype $;
   datalines;
Matt,    Matt,    Person,
X,,               Person,
Raleigh, Raleigh, City,
BBQ,,             Restaurant, BBQ
;
data mylib.LinksSocialQuery;
   infile datalines dsd;
   length from $40. to $40. connection $20.;
   input from $ to $ connection $;
   datalines;
Matt, X,       friends
X,    Matt,    friends
X,    Raleigh, lives in
X,    BBQ,     likes
;

Output 2.15.4 displays the output data table mylib.OutMatchNodes. For this query, three friends (X) match the specified criteria: Rob, Chuck, and Jack.

Output 2.15.4: Node Mappings for Friends Who Like Barbecue and Live in Raleigh

matchnodeQnodelabeltypesubtype
1BBQThe Pit AuthenticThe Pit AuthenticRestaurantBBQ
1MattMattMattPerson 
1RaleighRaleighRaleighCity 
1XChuckChuckPerson 
2BBQRed Hot BlueRed Hot BlueRestaurantBBQ
2MattMattMattPerson 
2RaleighRaleighRaleighCity 
2XJackJackPerson 
3BBQThe Pit AuthenticThe Pit AuthenticRestaurantBBQ
3MattMattMattPerson 
3RaleighRaleighRaleighCity 
3XRobRobPerson 


Output 2.15.5 displays the output data table mylib.OutMatchLinks.

Output 2.15.5: Subgraphs for Friends Who Like Barbecue and Live in Raleigh

matchfromtoconnection
1ChuckMattfriends
1ChuckRaleighlives in
1ChuckThe Pit Authenticlikes
1MattChuckfriends
2JackMattfriends
2JackRaleighlives in
2JackRed Hot Bluelikes
2MattJackfriends
3MattRobfriends
3RobMattfriends
3RobRaleighlives in
3RobThe Pit Authenticlikes


Finally, you might want to find "a pair of people, at least one of whom is a friend of Matt, who like the same barbecue restaurant (with rating of 9 or higher), live in Raleigh, and are friends of each other." This pattern is shown in Figure 235.

Figure 235: Query Graph Q

Query Graph


In order to construct this pattern, the query graph can be represented using the data that are created by the following DATA steps:

data mylib.NodesSocialQuery;
   infile datalines dsd;
   length node $40. label $40. type $40. subtype $20.;
   input node $ label $ type $ subtype $;
   datalines;
Matt,    Matt,    Person,
X,,               Person,
Y,,               Person,
Raleigh, Raleigh, City,
BBQ,,             Restaurant, BBQ
;
data mylib.LinksSocialQuery;
   infile datalines dsd;
   length from $40. to $40. connection $20.;
   input from $ to $ connection $;
   datalines;
Matt, X,       friends
X,    Matt,    friends
X,    Raleigh, lives in
Y,    Raleigh, lives in
X,    BBQ,     likes
Y,    BBQ,     likes
X,    Y,       friends
Y,    X,       friends
;

The query node Matt must be a person with the node attribute label=Matt. The query nodes, X and Y, can be any pair of people, at least one of whom is a friend of Matt and who both live in Raleigh. The query node BBQ must be a barbecue restaurant (that is, type=Restaurant and subtype=BBQ) that is liked by both persons X and Y with a rating of at least 9. Person X and person Y must be friends with Matt.

In order to enforce that the restaurant was rated with a value of at least limitRating, you can use the following FCMP link filter function:

%macro linkPairFilterCode();
   function myLinkFilter(connectionQ $, rating, limitRating);
      if (connectionQ='likes') then return (rating >= limitRating);
      else return (1);
   endsub;
%mend linkPairFilterCode;

The following statements find all subgraphs that have the specified pattern:

proc network
   direction        = directed
   nodes            = mylib.NodesSocial
   links            = mylib.LinksSocial
   nodesQuery       = mylib.NodesSocialQuery
   linksQuery       = mylib.LinksSocialQuery;
   nodesVar
      vars          = (label type subtype);
   linksVar
      vars          = (connection rating);
   nodesQueryVar
      vars          = (label type subtype);
   linksQueryVar
      vars          = (connection);
   patternMatch
      code          = "%linkPairFilterCode()"
      linkFilter    = myLinkFilter(linksQuery.connection,links.rating,9)
      outMatchNodes = mylib.OutMatchNodes
      outMatchLinks = mylib.OutMatchLinks;
run;

Output 2.15.6 displays the output data table mylib.OutMatchNodes. For this query, only one pair of friends (Jack and Natalia) matches the specified criteria.

Output 2.15.6: Node Mapping for a Pair of Friends

matchnodeQnodelabeltypesubtype
1BBQRed Hot BlueRed Hot BlueRestaurantBBQ
1MattMattMattPerson 
1RaleighRaleighRaleighCity 
1XJackJackPerson 
1YNataliaNataliaPerson 


Output 2.15.7 displays the output data table mylib.OutMatchLinks.

Output 2.15.7: Subgraph for a Pair of Friends

matchfromtoconnectionrating
1JackMattfriends.
1JackNataliafriends.
1JackRaleighlives in.
1JackRed Hot Bluelikes9
1MattJackfriends.
1NataliaJackfriends.
1NataliaRaleighlives in.
1NataliaRed Hot Bluelikes9


The result is shown graphically in Figure 236.

Figure 236: Subgraph for a Pair of Friends

Subgraph for a Pair of Friends


Last updated: August 07, 2026