last modified: 15 February, 2019

Overview

This is a set of functions designed to identify founding females in a pedigree, extracting their maternal lineages and plotting these sub-pedigrees. The driving force behind the development of this piece of work was to track mitochondrial inheritence patterns, but with some additional tweaks it could have many other uses.

Here is an example pedigree diagram (from the Norfolk Island population) showing founding Polynesian maternal lineages in colour. Complex NI pedigree source: Benton et al., 2015. ‘Mutiny on the Bounty’: The Genetic History of Norfolk Island reveals extreme gender biased admixture

The idea behind the image is clear, however it is rather difficult to easily visualise the separate lineages. Hence I developed the following approach in R using a combination of existing packages and some custom functions. Using the below we now have the ability to:

  • extract all mothers from a pedigree file
  • trace back a mothers ID to her maternal founder within the pedigree
    • identify all such maternal founders
  • explore the frequency of these founders lineages (identifying those that are largest/smallest, etc.)
  • given a founder ID, extract her maternal lineage
  • extract a given lineage and create a sub-pedigree plot

Load the required packages

# load packages
require(kinship2)
require(pedigree)
require(tidyverse)

Load the pedigree data

# load data
setwd('/data/PostDoc/NI_pedigree')
# load pedigree
niped <- read.table('NI_UUID_pedigree.ped', head = F)
# add colnames for ease of use
colnames(niped) <- c('FID', 'IID', 'PID', 'MID', 'SEX', 'PHENO')

The pedigree is contained in a .ped (pedigree), very similar to the plink file format of the same name. Here is the head of the pedigree file once loaded into R, it has 6 columns:

# head of the pedigree
head(niped)
##   FID    IID    PID    MID SEX PHENO
## 1   1 110630    790    800   2    -9
## 2   1 110850 111740 333130   2    -9
## 3   1 111280    933     59   2    -9
## 4   1 111830 169270 400523   2    -9
## 5   1 310881      0      0   2    -9
## 6   1 343481   1716 319731   2    -9

Here is a breakdown of the columns:

  • FID = family ID (as NI is one large family this is 1 for everybody), if you imagine there being separate families, say trios, then each would get assigned a different number.
  • IID = individual ID (sample ID)
  • PID = paternal ID (father)
  • MID = maternal ID (mother)
  • SEX = obvious (1 is male, 2 is female)
  • PHENO = phenotype data, this is set to missing (-9) because there is no analysis to be performed. One might include something like BMI in this column when performing an association analysis using a tool like plink.

1. get_mothers()

# define unique mothers 
get_mothers <- function(pedigree) {
  pedigree %>% 
    filter(SEX == 2) %>%
    select(MID) %>%
    unique %>%
    filter(. > 0) %>%
    as.matrix %>%
    as.list 
}
# get list of all mothers in pedigree
mothers <- get_mothers(pedigree = niped)

2. trace_mother()

# function to trace a 'founding' mother
trace_mother <- function(pedigree, motherID) {
  results <- NULL
  x <- motherID
  while (x != 0) {
    z <- x
    x <- pedigree %>% 
      filter(IID == x) %>% 
      select(MID) %>% 
      as.character
    results <- rbind(results, data.frame(IID = z, MID = x))
  }  
  results <- results[dim(results)[1]:1,]
  return(results)
}

We can apply the trace_mother() function on a single sample:

# single use of the function, direct maternal line back to founder from a single female
trace_mother(pedigree = niped, motherID = '400440')
##       IID    MID
## 10    691      0
## 9      34    691
## 8     253     34
## 7     449    253
## 6     453    449
## 5     342    453
## 4     345    342
## 3  400523    345
## 2  111830 400523
## 1  400440 111830

Probably more useful, however, is the ability to run this across all mothers within a pedigree:

# apply across all mothers and get lists tracing back to 'founding' individuals
mother_lists <- lapply(mothers, trace_mother, pedigree = niped)

3. founding_mothers()

# get all unique maternal founders
founding_mothers <- function(mother_lists) {
  sapply(mother_lists, '[[',1) %>%
    sapply(., '[[',1) %>%
    unique %>%
    as.numeric %>%
    sort 
}
# use the above function to get a sorted vector of founding mothers
mt_founders <- founding_mothers(mother_lists = mother_lists)

4. maternal_freq()

# identify the mothers with largest maternal lines
maternal_freq <- function(mother_list, frequency, plot = FALSE) {
  # generate freq table
  results <-
    sapply(mother_list, '[[',1) %>%
    sapply(., '[[',1) %>%
    as.data.frame %>% 
    rename(., Maternal_ID = 1) %>%
    mutate_at(1, as.character) %>%
    plyr::count() %>%
    arrange(-freq) %>%
    filter(freq >= frequency)
  # plot if required
  if(plot == TRUE) {
    return(list(results, barplot(results$freq, names.arg = results$Maternal_ID, main = 'most frequent maternal founders',
                                 xlab = 'Maternal ID', ylab = 'Freq', las = 2, col = 'cadetblue')))  
  } else {
    return(results)
  }
}

This function in practice:

# provide a threshold and create a table of maternal frequencies
maternal_freq(mother_list = mother_lists, frequency = 3)
##    Maternal_ID freq
## 1          691  115
## 2          694   58
## 3          242   26
## 4           13    8
## 5         1597    8
## 6          490    7
## 7          522    6
## 8         1878    5
## 9           23    5
## 10         208    4
## 11        2212    4
## 12        3018    4
## 13         219    3
## 14        2462    3

…and with a plot:

# create plot if required
maternal_freq(mother_list = mother_lists, frequency = 5, plot = T)

5. trace_maternal_line()

# starting with a MID trace all maternal descendents
trace_maternal_line <- function(pedigree, motherID) {
  x <- motherID
  results <- list(as.numeric(x)) # add founding mother as first entry in list
  counter <- 1
  while (length(x) > 0) {
    counter <- counter + 1
    # x <- pedigree[pedigree$MID %in% x & pedigree$SEX == 2,]$IID # this will pull only female offspring of the searched mother
    x <- niped[niped$MID %in% x,]$IID # this will pull all offspring
    results[[counter]] <- x
  }  
  # remove empty entry and return results
  return(results[-length(results)])
}
# examples
trace_maternal_line(pedigree = niped, motherID = '691') # red in pedigree plot
## [[1]]
## [1] 691
## 
## [[2]]
## [1]  34 532 692 696
## 
## [[3]]
##  [1]   31   32  251  252  253  255  256  326  533  535  536  537 2111
## 
## [[4]]
##  [1]   22  147  148  150  151  157  176  249  250  279  335  426  449  472
## [15]  541  542  543  626  627  629  630  635  643  644  710 1030 1031 1032
## [29] 1033 1039 1040 1162 1674 2064 2113 2114 2115 2116 2119 2131 2132 2133
## [43] 2135
## 
## [[5]]
##  [1]   56   57  161  163  286  315  341  376  408  412  414  427  429  430
## [15]  434  435  441  450  451  452  453  454  456  475  481  651  711  713
## [29]  716  718  727  777  780  782  821  822  824  911  912  917  973 1041
## [43] 1079 1081 1128 1163 1164 1167 1170 1172 1598 1894 1902 1917 2124 2125
## [57] 2127 2222 2345 2354 2358 2360 2417 2420 5044 5082 5092
## 
## [[6]]
##  [1] 168050 255670 400093 125660 320320 317710     46     59     60     61
## [11]     62    199    316    318    342    377    391    482    496    519
## [21]    520    655    719    721    722    730    731    732    826    829
## [31]    859    860    896    934    946    968    974   1087   1106   1108
## [41]   1129   1130   1131   1132   1175   1179   1181   1196   1270   1298
## [51]   1431   1437   1438   1522   1600   1604   1606   1611   1614   1644
## [61]   1645   1646   1661   1877   1896   1904   1906   1910   1918   2009
## [71]   2228   2288   2427   2574   2575   2578   2579   2580   2656   3158
## [81]   3362   4050   4886
## 
## [[7]]
##  [1] 111280 111890 111990 110820 320620 124670 362060 125580 328820 315981
## [11] 400107 400389 330050 311760 168180 316910 311360 211340 217310 212910
## [21] 245120 400096 400226 400301 400370 400519 400520     63 400012    320
## [31]    344    345    346    656    723    897    935 400115   1091   1115
## [41]   1134   1198   1230   1263   1321   1322   1323   1324   1524   1542
## [51]   1615   1659   1664   1667   1669   1672   1720   1721   1747   1781
## [61]   1846   1849   1852   1925   1953   2017   2430   2445 400087   2602
## [71]   2603   2618   2621   2623   2757   2760   2911   2992   2994   2997
## [81]   4881   5310
## 
## [[8]]
##  [1] 317801 331100 111460 314210 336510 310601 310121 322861 310711 124480
## [11] 311160 336600 366851 228260 271360 255711 400024 400070 400162 400232
## [21] 400381 400523 216261 400785 311700 110550 310820 320450 344870 343430
## [31] 125270 312370 316320 312930 317650 169020 310040 169270 232420 228350
## [41] 215590 212390 400011 400305 400643 400671    354    503   1005   1547
## [51]   1576   1616   1802   1851   1853   1926   1927 400726   2667   4865
## 
## [[9]]
##  [1] 111830 317941 110500 111770 312801 125900 136150 375731 332031 311071
## [11] 214050 216640 400310 400315 320490 312590 314200 219560 267620 228151
## [21] 227220 400194 400341 400554 400646 400660 400672 400765 400659 400317
## 
## [[10]]
## [1] 111800 217943 212804 400208 400440 400441 269400
trace_maternal_line(pedigree = niped, motherID = '242') # darkblue in pedigree plot
## [[1]]
## [1] 242
## 
## [[2]]
## [1] 244 245 246 247 248 528
## 
## [[3]]
##  [1]  258  259  261  262  267  425  446  447  448 2150
## 
## [[4]]
##  [1]  190  328  333  334  458  459  470 1063 2186 2188 2193 2431 2741
## 
## [[5]]
##  [1]  193  194  195  198  488  868  873  875 1054 1067 1271 2434 2694 2840
## [15] 2843 2845 4949
## 
## [[6]]
##  [1] 344050 168720 400311    478    479    783   1071   1117   1187   1188
## [11]   1189   1190   3047   4870
## 
## [[7]]
## [1] 356930 111090 250921 400634 400399   1118
## 
## [[8]]
## [1] 400644 327200 400619
trace_maternal_line(pedigree = niped, motherID = '522') # lightblue in pedigree plot
## [[1]]
## [1] 522
## 
## [[2]]
## [1] 523 524 525
## 
## [[3]]
## [1]  424 2106 2109
## 
## [[4]]
## [1] 2155 2156 4980
## 
## [[5]]
## [1] 4888 4951 4987
## 
## [[6]]
## [1] 4871 4877
## 
## [[7]]
## [1] 4864
trace_maternal_line(pedigree = niped, motherID = '1597')
## [[1]]
## [1] 1597
## 
## [[2]]
## [1]  288 2334 2335
## 
## [[3]]
## [1]  289  291 2749 2750 2752 3055
## 
## [[4]]
## [1] 301001 400521 400543    307    308    878   1223   1125
## 
## [[5]]
## [1] 301008 400470 334380 316400 301007 125140 313570 400104
trace_maternal_line(pedigree = niped, motherID = '13')
## [[1]]
## [1] 13
## 
## [[2]]
## [1] 364020 312960 125850 168790      9     15     17     19     20
## 
## [[3]]
##  [1] 333760 333130 212771 213991 319420 345601 316160 316960 219390    112
## [11] 213992
## 
## [[4]]
## [1] 110850 338630 400516 400263 400512
# count female decendents
trace_maternal_line(pedigree = niped, motherID = '691') %>% unlist %>% length
## [1] 390
trace_maternal_line(pedigree = niped, motherID = '694') %>% unlist %>% length
## [1] 167
trace_maternal_line(pedigree = niped, motherID = '242') %>% unlist %>% length
## [1] 70
trace_maternal_line(pedigree = niped, motherID = '13') %>% unlist %>% length
## [1] 26
trace_maternal_line(pedigree = niped, motherID = '1597') %>% unlist %>% length
## [1] 26
trace_maternal_line(pedigree = niped, motherID = '490') %>% unlist %>% length
## [1] 22
trace_maternal_line(pedigree = niped, motherID = '522') %>% unlist %>% length
## [1] 16
trace_maternal_line(pedigree = niped, motherID = '1954') %>% unlist %>% length
## [1] 4

6. split_maternal_ped()

# create sub-pedigrees of mt lineages
# need kinship2 and pedigree for this function
# I will work on building in package checking later
split_maternal_ped <- function(pedigree, motherID) {
    # determine 'affecteds' 
  search_IDs <- trace_maternal_line(pedigree = pedigree, motherID = motherID) %>% unlist
    # pedigree splitting
  ped <- data.frame(pedigree$IID, pedigree$PID, pedigree$MID)
  (ord <- orderPed(ped))
  ped <- ped[order(ord),]
  # trim out only 'affecteds' - all female descendants of a given founder
  yn <- trimPed(ped, data = (ped$pedigree.IID %in% search_IDs), ngenback = 0)
  ped <- ped[yn,]
  colnames(ped) <- c('IID', 'PID', 'MID')
  ped <- merge(ped, pedigree, by = c('IID', 'PID', 'MID'), sort = F)
  # get dad ids
  dad.ids <- 
    ped %>% 
    filter(PID > 0) %>% 
    select(PID) %>%
    unlist %>%
    unique
  # check if any of these are already in ped, if so remove
  dad.ids <- dad.ids[!(dad.ids %in% ped$IID)]
  # grab father information and set thier PID and MID to 0 for plotting purposes
  res.out <- pedigree %>% filter(IID %in% dad.ids)
  res.out$PID = 0
  res.out$MID = 0
  # add father information back into the ped
  ped <- rbind(res.out, ped)
  # create a pedigree to plot using kinship2 function
  test.ped <- pedigree(id = ped$IID, dadid = ped$PID, momid = ped$MID, sex = ped$SEX)
  # plotting
  return(list(plot.pedigree(test.ped, affected = ped$SEX, cex = 0.8, symbolsize = 0.8, width = 40, align = T), ped[-6]))
}

A few tests of the above:

# split out the given maternal lineage and create a pedigree diagram
split_maternal_ped(pedigree = niped, motherID = '490')

# split out the given maternal lineage and create a pedigree diagram
split_maternal_ped(pedigree = niped, motherID = '1597')

# split out the given maternal lineage and create a pedigree diagram
split_maternal_ped(pedigree = niped, motherID = '13')

# split out the given maternal lineage and create a pedigree diagram
split_maternal_ped(pedigree = niped, motherID = '242')

# split out the given maternal lineage and create a pedigree diagram
split_maternal_ped(pedigree = niped, motherID = '694')

Estimating “transmissions”

# get pedigree object
ped_test <- split_maternal_ped(pedigree = niped, motherID = '13')

# get number of generations (maternal founder is set to 1)
ped_data <- data.frame(ped_test[[2]], generation = ped_test[[1]]$y)
# create the maternal founder transmission index (number of transmissions from maternal founder to given individual)
ped_data$M0_trans <- ped_data$generation - 1
# filter out new founders that aren't original founders
origFounders <- ped_data %>% filter(M0_trans == 0)  # get original founders
foundersRemoved <- ped_data %>% filter(PID > 0 & MID > 0)  # filter 'new' founders 
ped_data <- rbind(origFounders, foundersRemoved)  # recreate ped_data

# now all you need to do is add the `M0_trans` from 2 individuals to get the number of transmissons between them
#
I1 <- "338630"
I2 <- "400512"
# the below will give number of transmissions between the 2
ped_data[ped_data$IID == I1,]$M0_trans + ped_data[ped_data$IID == I2,]$M0_trans
## [1] 6

The above will allow you to explore transmission between a pair of samples defined by the user. If you want to batch process this through all possible pairs in a given pedigree it would look something like this:

# create vector of all ids for selected pedigree
idList <- sort(ped_data$IID)
# create an object of all possible pairwise comparisons
pedPairs <- t(combn(idList, 2))

# create a new matrix of the appropriate dimensions and fill with pairs
# these people don't provie any meaningful maternal information
transMatrix <- matrix(nrow = nrow(pedPairs), ncol = 3)
transMatrix[ , 1] <- pedPairs[ , 1]
transMatrix[ , 2] <- pedPairs[ , 2]
# provide colnames to the matrix
colnames(transMatrix) <- c("ID1", "ID2", "number_of_trans")

# run across all pairs in the above object and fill the 3rd columns of the matrix with
# the number of transmissions between the pair of samples
for (pair in 1:nrow(pedPairs)) {
  
  # define the pair
  I1 <- pedPairs[pair, 1]
  I2 <- pedPairs[pair, 2]
  
  # get the number of transmissions and assign to the correct position in the created matrix
  transMatrix[ pair , 3] <- ped_data[ped_data$IID == I1,]$M0_trans + ped_data[ped_data$IID == I2,]$M0_trans
  
}

# convert to dataframe
transMatrix <- as.data.frame(transMatrix)
# look at random sample of data
sample_n(transMatrix, 10) # sample_n assumes use of dplyr
##        ID1    ID2 number_of_trans
## 286 312960 316160               3
## 82      15 168790               2
## 347 364020 400512               4
## 323 319420 400516               5
## 310 316960 338630               5
## 164    112 168790               3
## 77      15     19               2
## 348 364020 400516               4
## 114     17 333760               3
## 202 125850 213992               3

The above example was run on a small sub-pedigree containing 351 total pairs, it completed in less than a second. Obviously as the number of pairs increases it will take longer. It’s not best practice to use for loops but this was a very quick solution to the problem at hand and it appears to be working well enough for now. Could look into using something like apply in the future if required.

Most Recent Common Maternal Ancestor (MRCMA) transmission

NOTE: in the above, the code was exploring the number of transmissions via the founding maternal pedigree member. This isn’t going to be of interest and doesn’t actually make a whole lot of sense. What is more interesting is the number of transmissions between a pair of samples to their most recent commom maternal ancestor. This is a bit trickier to implement, but the below code will do this.

7. recentCommonMaternal()

First, we need a function to find the most recent common maternal ancestor (mrcma) for a given pair of samples:

# return mrcma for a given pair
# TODO: optimise this!!
recentCommonMaternal <- function(individual1, individual2) {

  # create lists of maternal relatives
  lineage1 <- as.character(trace_mother(pedigree = niped, motherID = individual1)[[1]])
  lineage2 <- as.character(trace_mother(pedigree = niped, motherID = individual2)[[1]])
  # find most recent common maternal ancestor
  lineage1[lineage1 %in% lineage2] %>% tail(., n=1)  
  
}

We can then use the above function to add the information (mrcma) to an object alongside the ids of the pairs of individuals that share that mrcma. We can then calculate the number of transmissions between them using this equation:

( individual 1 generation - mrcma generation ) + ( individual 2 generation - mrcma generation )

All this information can be then store into a single object, which has 5 columns: maternalFounder | ind1 | ind2 | mrcma | mrcma_transmissions

8. calc_maternalTrans()

Here is the code (this runs for all pairs of a given maternal founder):

# create a function to take maternal ID and generate transmission data for pairs of samples
calc_maternalTrans <- function(maternalFounder) {
  
  # get pedigree object
  ped_test <- split_maternal_ped(pedigree = niped, motherID = maternalFounder)
  # get number of generations (maternal founder is set to 1)
  ped_data <- data.frame(ped_test[[2]], generation = ped_test[[1]]$y)
  # create the maternal founder transmission index (number of transmissions from maternal founder to given individual)
  ped_data$M0_trans <- ped_data$generation - 1
  # filter out new founders that aren't original founders
  origFounders <- ped_data %>% filter(M0_trans == 0 & SEX == 2)  # get original founders
  foundersRemoved <- ped_data %>% filter(PID > 0 & MID > 0)  # filter 'new' founders 
  ped_data <- rbind(origFounders, foundersRemoved)  # recreate ped_data
  
  # create vector of all ids for selected pedigree
  idList <- sort(ped_data$IID)
  # create an object of all possible pairwise comparisons
  pedPairs <- t(combn(idList, 2))
  
  # convert to data frame
  # this will slow things down, but can look to optimise later
  # TODO: optimise this!!
  pedPairs <- as.data.frame(pedPairs)
  # add column names for the individuals in a pair
  colnames(pedPairs) <- c("ind1", "ind2")
  # create column for most recent common maternal ancestor (mrcma)
  pedPairs$mrcma <- NA
  # create column for number of transmissions
  pedPairs$mrcma_transmissions <- NA
  # create a column to store the founder of the given maternal sub-pedigree
  pedPairs$maternalFounder <- maternalFounder
  
  # for loop
  # TODO: optimise this!!!!
  for (i in c(1:nrow(pedPairs))) {
    
    # get the most recent common maternal ancestor (not the original founding maternal ancestor)
    pedPairs$mrcma[i] <- recentCommonMaternal(individual1 = pedPairs[i,1], individual2 = pedPairs[i,2])
    # grab the generation of each of the 3 different individuals
    ind1Gen <- ped_data[ped_data$IID == pedPairs[i,1],]$generation
    ind2Gen <- ped_data[ped_data$IID == pedPairs[i,2],]$generation
    mrcmaGen <- ped_data[ped_data$IID == pedPairs[i,3],]$generation
    # the equation then becomes:
    # ( individual 1 generation - mrcma generation ) + ( individual 2 generation - mrcma generation )
    pedPairs$mrcma_transmissions[i] <- (ind1Gen - mrcmaGen) + (ind2Gen - mrcmaGen)
    
  }
  # return object (reordered with founder as first column)
  return(pedPairs <- pedPairs[c(5,1:4)])
}

# test function
maternalTest <- calc_maternalTrans(13)

# look at random sample of data
sample_n(maternalTest, 10) # sample_n assumes use of dplyr
##     maternalFounder   ind1   ind2 mrcma mrcma_transmissions
## 27               13     13     17    13                   1
## 108              13     19 333130    13                   3
## 190              13 168790 212771    13                   3
## 49               13     13 400516    13                   3
## 318              13 345601 400512    15                   3
## 156              13 110850 168790    13                   4
## 74               13     17     20    13                   2
## 271              13 316160 316960    13                   4
## 235              13 213992 219390    13                   4
## 200              13 168790 338630    13                   4

We can now batch through a list of maternal founders to calculate all pairwise maternal transmissions and return these as an object (the next bit of code takes a while to run).

# list of maternal IDs
maternal_IDs <- c(13, 1597, 691, 694, 242, 490, 522)
# if you want to use lapply and wrangle back into dataframe
maternalTransmissions <- lapply(maternal_IDs, calc_maternalTrans) %>% do.call(rbind, .)

# ouput to file
write.csv(maternalTransmissions, "NI_maternalTransmissions_20190215.csv", row.names = F, quote = F)
# look at random sample
sample_n(maternalTransmissions, 10)
##       maternalFounder   ind1   ind2 mrcma mrcma_transmissions
## 19703             691    434   1896   426                   4
## 21705             691    452   1902   253                   5
## 13866             691    335   2228    34                   6
## 60379             691   1918 400381   253                   8
## 37237             691    824   1644   536                   7
## 68830             691   4886 322861    34                  10
## 4645              691     62   1298   691                  10
## 89449             694 168830 362911   695                  10
## 35088             691    730 217943   691                  14
## 61806             691   2113   2127  2113                   2

Note: there is a fair bit of omtimising to be done in the above code. It is going to run quite slowly on any of the larger maternal pedigrees. It is only something that needs to be run once though and the object can be output to a file. Please be patient if you are running on a lot of large pedigrees. :)

We can now look at the breakdown of statistics across this transmission object:

# number of maternal transmissions per founder
table(maternalTransmissions$maternalFounder)
## 
##    13   242   490   522   691   694  1597 
##   325  2415   231   120 75855 13861   325
# or a plot
barplot(table(maternalTransmissions$maternalFounder), xlab = "maternal founder", ylab = "total number of maternal transmissions")

# number of total transmissions broken down into category
table(maternalTransmissions$mrcma_transmissions)
## 
##     0     1     2     3     4     5     6     7     8     9    10    11 
##     1   692  1483  2589  4152  6120  8113  9837 10752 11120 10609  9320 
##    12    13    14    15    16    17    18    19 
##  7358  5163  3188  1635   697   237    57     9
# or a plot
barplot(table(maternalTransmissions$mrcma_transmissions), xlab = "number of transmissions (mrcma)", ylab = "freq")

We can now create a unique ‘key’ by combining the three different ids and then this can be used to pull out information from pairs of interest:

# create a unique id based on the 3 different ids
maternalTransmissions$UUID <- with(maternalTransmissions, paste0(maternalFounder, ind1, ind2))

# take a random sample of these unique ids 
testID <- sample(maternalTransmissions$UUID, 50)

# subset these from the larger data 
maternalTransmissions[maternalTransmissions$UUID %in% testID,]
##       maternalFounder   ind1   ind2 mrcma mrcma_transmissions
## 4617              691     62   1041   691                   9
## 5711              691    148    718   532                   5
## 5744              691    148   1032   532                   4
## 6705              691    151 322861   691                  10
## 6851              691    157    860   532                   7
## 9769              691    252    643    34                   3
## 11138             691    256 400208    34                   9
## 12032             691    315   1611   253                   5
## 14681             691    342 328820   691                  11
## 18405             691    426   2997   691                   9
## 23871             691    482    630    34                   6
## 28810             691    629 124480   253                   6
## 30511             691    655   1164    34                   7
## 32668             691    713   1927   691                  11
## 34839             691    727 320620   691                  10
## 35059             691    730 110550   176                   7
## 35384             691    731 255711   691                  12
## 36356             691    782   1131   691                   9
## 38005             691    859    897   253                   7
## 41001             691    973   1039   691                   9
## 41308             691    974   1576    34                  13
## 42469             691   1032 125580   537                   6
## 44919             691   1108   1614   253                   6
## 45372             691   1115 400643   253                  10
## 47844             691   1170   1524    34                   8
## 51469             691   1431 315981   253                   7
## 52218             691   1524   1721   691                  12
## 52909             691   1576   2135    34                   9
## 53334             691   1600   2124    34                   7
## 56061             691   1667   2580   253                   7
## 57121             691   1721 269400   691                  15
## 62689             691   2124   5092  2111                   4
## 63454             691   2132 400523    34                   8
## 64056             691   2228 331100    34                  10
## 64343             691   2345 310820  2345                   3
## 64849             691   2360 400162    34                   9
## 66946             691   2623 125580   691                  14
## 71258             691 168050 212804    34                  12
## 72002             691 212910 375731   691                  15
## 72442             691 217310 316910    34                  10
## 72674             691 219560 400672    34                  15
## 72902             691 228260 400087   824                   5
## 73909             691 310820 362060    34                  11
## 74202             691 311700 400226    34                  12
## 74888             691 317650 400310   691                  16
## 84196             694   1595   2367  1595                   2
## 85872             694   1708 311660   695                  10
## 86324             694   1756 216304  1752                   7
## 88506             694   3025 311020   694                  10
## 88840             694   3219 169290   694                  12
##                  UUID
## 4617        691621041
## 5711        691148718
## 5744       6911481032
## 6705     691151322861
## 6851        691157860
## 9769        691252643
## 11138    691256400208
## 12032      6913151611
## 14681    691342328820
## 18405      6914262997
## 23871       691482630
## 28810    691629124480
## 30511      6916551164
## 32668      6917131927
## 34839    691727320620
## 35059    691730110550
## 35384    691731255711
## 36356      6917821131
## 38005       691859897
## 41001      6919731039
## 41308      6919741576
## 42469   6911032125580
## 44919     69111081614
## 45372   6911115400643
## 47844     69111701524
## 51469   6911431315981
## 52218     69115241721
## 52909     69115762135
## 53334     69116002124
## 56061     69116672580
## 57121   6911721269400
## 62689     69121245092
## 63454   6912132400523
## 64056   6912228331100
## 64343   6912345310820
## 64849   6912360400162
## 66946   6912623125580
## 71258 691168050212804
## 72002 691212910375731
## 72442 691217310316910
## 72674 691219560400672
## 72902 691228260400087
## 73909 691310820362060
## 74202 691311700400226
## 74888 691317650400310
## 84196     69415952367
## 85872   6941708311660
## 86324   6941756216304
## 88506   6943025311020
## 88840   6943219169290

Where I have taken a random sample of unique ids you can load in your own from something like a text or excel file.