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

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

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 andsubtype=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
| match | nodeQ | node | label | type | subtype |
|---|---|---|---|---|---|
| 1 | BBQ | Red Hot Blue | Red Hot Blue | Restaurant | BBQ |
| 1 | Matt | Matt | Matt | Person | |
| 1 | X | Bryan | Bryan | Person | |
| 2 | BBQ | The Pit Authentic | The Pit Authentic | Restaurant | BBQ |
| 2 | Matt | Matt | Matt | Person | |
| 2 | X | Chuck | Chuck | Person | |
| 3 | BBQ | Red Hot Blue | Red Hot Blue | Restaurant | BBQ |
| 3 | Matt | Matt | Matt | Person | |
| 3 | X | Jack | Jack | Person | |
| 4 | BBQ | The Pit Authentic | The Pit Authentic | Restaurant | BBQ |
| 4 | Matt | Matt | Matt | Person | |
| 4 | X | Rob | Rob | Person | |
| 5 | BBQ | JimmyJs | JimmyJs | Restaurant | BBQ |
| 5 | Matt | Matt | Matt | Person | |
| 5 | X | Stephen | Stephen | Person |
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
| match | from | to | connection |
|---|---|---|---|
| 1 | Bryan | Matt | friends |
| 1 | Bryan | Red Hot Blue | likes |
| 1 | Matt | Bryan | friends |
| 2 | Chuck | Matt | friends |
| 2 | Chuck | The Pit Authentic | likes |
| 2 | Matt | Chuck | friends |
| 3 | Jack | Matt | friends |
| 3 | Jack | Red Hot Blue | likes |
| 3 | Matt | Jack | friends |
| 4 | Matt | Rob | friends |
| 4 | Rob | Matt | friends |
| 4 | Rob | The Pit Authentic | likes |
| 5 | Matt | Stephen | friends |
| 5 | Stephen | JimmyJs | likes |
| 5 | Stephen | Matt | friends |
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

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
| match | nodeQ | node | label | type | subtype |
|---|---|---|---|---|---|
| 1 | BBQ | The Pit Authentic | The Pit Authentic | Restaurant | BBQ |
| 1 | Matt | Matt | Matt | Person | |
| 1 | Raleigh | Raleigh | Raleigh | City | |
| 1 | X | Chuck | Chuck | Person | |
| 2 | BBQ | Red Hot Blue | Red Hot Blue | Restaurant | BBQ |
| 2 | Matt | Matt | Matt | Person | |
| 2 | Raleigh | Raleigh | Raleigh | City | |
| 2 | X | Jack | Jack | Person | |
| 3 | BBQ | The Pit Authentic | The Pit Authentic | Restaurant | BBQ |
| 3 | Matt | Matt | Matt | Person | |
| 3 | Raleigh | Raleigh | Raleigh | City | |
| 3 | X | Rob | Rob | Person |
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
| match | from | to | connection |
|---|---|---|---|
| 1 | Chuck | Matt | friends |
| 1 | Chuck | Raleigh | lives in |
| 1 | Chuck | The Pit Authentic | likes |
| 1 | Matt | Chuck | friends |
| 2 | Jack | Matt | friends |
| 2 | Jack | Raleigh | lives in |
| 2 | Jack | Red Hot Blue | likes |
| 2 | Matt | Jack | friends |
| 3 | Matt | Rob | friends |
| 3 | Rob | Matt | friends |
| 3 | Rob | Raleigh | lives in |
| 3 | Rob | The Pit Authentic | likes |
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

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
| match | nodeQ | node | label | type | subtype |
|---|---|---|---|---|---|
| 1 | BBQ | Red Hot Blue | Red Hot Blue | Restaurant | BBQ |
| 1 | Matt | Matt | Matt | Person | |
| 1 | Raleigh | Raleigh | Raleigh | City | |
| 1 | X | Jack | Jack | Person | |
| 1 | Y | Natalia | Natalia | Person |
Output 2.15.7 displays the output data table mylib.OutMatchLinks.
Output 2.15.7: Subgraph for a Pair of Friends
| match | from | to | connection | rating |
|---|---|---|---|---|
| 1 | Jack | Matt | friends | . |
| 1 | Jack | Natalia | friends | . |
| 1 | Jack | Raleigh | lives in | . |
| 1 | Jack | Red Hot Blue | likes | 9 |
| 1 | Matt | Jack | friends | . |
| 1 | Natalia | Jack | friends | . |
| 1 | Natalia | Raleigh | lives in | . |
| 1 | Natalia | Red Hot Blue | likes | 9 |
The result is shown graphically in Figure 236.
Figure 236: Subgraph for a Pair of Friends
