Converting individual row data into pairwise data using basic R

Note: This blog post is just about how to get your data from individual to pairwise, which is the format you would need to run an APIM analysis. Originally, dyadR was an R package that would convert data from individual to pairwise, but it has depreciated. There is a more tidy way of doing this but I had some trouble with it, so here we're just using basic programming.

I recently stumbled upon the Actor Partner Interdependence Model (APIM), which I'm learning to use in one of my dyadic experiments. Basically it looks like the below model:


So an example of this could be a study that looks at the role of a partner's BMI on the actor's weight concerns (taken from Markey & Markey, 2013).


In order to conduct an APIM analysis, we need data in pairwise format.

Oftentimes we have data in individual format (one row per participant).
To illustrate this, this is what individual data looks like:
AAAAAA
BBBBBB


This is what pairwise data looks like: 
AAAAAABBBBBB
AAAAAABBBBBB


Here's the code that will do it. I'm giving credit to my partner, John, for writing all of this. 
Note that this will create a format that looks more like:
ABABABAB
rather than AAABBB, because I felt this was easier to check the dataframe for errors. But if you want it in this original format, just sort your columns.

Did it work for you? Do you have other feedback? Let us know!

Create fake dataset:
set.seed(123)
myData <- data.frame('dyad' = as.integer(c(1, 1, 2, 2)),
                     'person' = as.integer(c(1, 2, 1, 2)),
                     'x' = as.double(rnorm(4)),
                     'y' = as.double(rnorm(4)),
                     'z' = as.double(rnorm(4)))
My orig df looks like this: 

Function pairwise takes in the dataframe (data argument), a string for colname that identifies the group (group argument), and takes in a string for colname that identifies the person (id argument).

It then takes in a vector of strings that identifies columns you do not wish to convert to pairwise (e.g., Exclusion column, other variables you do not theoretically expect to be interdependent; colsToIgnore argument)*this argument is optional.

Finally, the default is to append an _A for actor variables and an _P for partner variables (actor, partner arguments), but you can specify:
pairwise <- function(data, group, id, colsToIgnore=c(), actor='_A', partner='_P') {
  
  if (is.null(colnames(data))) {
    warning('no data passed into pairwise')
    return()
  }
  
  # Require both group and id columns passed in
  if (!(group %in% colnames(data)) | !(id %in% colnames(data))) {
    warning('group column must be defined')
    return()
  }
  
  #instantiate the return data frame and allocate space
  staticColCount <- 2 + length(colsToIgnore)  # number of columns that are copied over as is
  pairwiseData <- data.frame(matrix(NA, nrow=nrow(data), ncol=(2 * (ncol(data) - staticColCount) + staticColCount)))
  
  newColNames <- function (colName) {
    if (colName != group & colName != id & !(colName %in% colsToIgnore))
      return(c(paste0(colName, actor), paste0(colName, partner)))
    
    return(colName)
  }
  
  #set new column names
  colnames(pairwiseData) <- unlist(sapply(colnames(data), newColNames))
  
  #copy over group and id columns
  pairwiseData[[group]] <- data[[group]]
  pairwiseData[[id]] <- data[[id]]
  
  if (length(colsToIgnore) > 0) {
    for (i in 1:length(colsToIgnore)){
      pairwiseData[[colsToIgnore[i]]] <- data[[colsToIgnore[i]]]
    }
  }
  
  rowIdx <- 1
  
  copyRowData <- function (row) {
    for (i in 1:length(names(row))) {
      currColName <-  names(row)[i]
      if (currColName != group & currColName != id & !(currColName %in% colsToIgnore)) {
        pairwiseData[rowIdx, paste0(currColName, actor)] <<- row[i]
        pairwiseData[pairwiseData[[id]] != row[id] & pairwiseData[[group]] == row[group], paste0(currColName, partner)] <<- row[i]
      }
    }
    rowIdx <<- rowIdx + 1
  }
  
  apply(data, 1, copyRowData)
  
  return(pairwiseData)
}
Create pairwise dataframe using example data, I told it to ignore x and y:
final <- pairwise(myData, group = "dyad", id = "person", colsToIgnore = c("x", "y"))
My new df looks like this: 


Comments

Popular Posts