Q:

R: Grouping by columns, regardless of order, then conducting function on tertiary column

I have the output from multiple TSdist functions to test the difference between multiple time series. The resultant matrix has been converted into a data frame using I have used melt to convert into a single data frame. With the first column representing the row ID as a column, the second representing the colnames. Im attempting to calculate the average similarity between the whole period.
Im attempting to group by the first two columns, performing and operation on the third. Here is an example data frame.
df <- data.frame(A = factor(x = c("A", "B", "A", "A"), levels = c("A", "B")),
             B = factor(x = c("B", "A", "A", "A"), levels = c("A", "B")),
             C= c(2,3,6,5))

Ive attempted to use dplyr to group by the first two columns. However, the location of the column needs to be ignored when performing the operation. For example the first row in the above data frame should be grouped with the second row as they are both A and B. With rows 3 and 4 naturally being grouped, performing a function on each group using the third column, eg. mean().
Thanks

A:

I can think of two ways to approach this using dplyr.  If the number of levels is low, you can just create a new variable of the interaction, and use fct_recode to fix things (e.g. BA to AB).
This solution looks like this:
library(dplyr)
library(forcats)
df %>%
  mutate(
    AB = interaction(A, B, sep = ""),
    AB = fct_recode(AB, AB = "BA")
  ) 

A more robust solution takes a few more steps, but should work regardless of the number of levels in your actual data set:
library(tidyr)
df %>%
  mutate(id = 1:length(A)) %>%
  gather(group_id, group, A:B) %>%
  group_by(id) %>%
  summarize(
    AB = paste0(sort(group), collapse = ""),
    C = C[1]
  )

A:

You could do ... (same idea as @MelissaKey's gather approach) ...
library(data.table)
setDT(df)

# add a grouping variable found by sorting and pasting the first two cols
df[, g := 
  vapply(transpose(.SD), function(x) paste(sort(x), collapse=" "), "", USE.NAMES = FALSE)
, .SDcols=1:2]

# aggregate the third column with it
df[, lapply(.SD, mean), by=g, .SDcols=3]

#      g   C
# 1: A B 2.5
# 2: A A 5.5

You can pass column names in .SDcols instead of positions, and it is generally better practice. See the first FAQ in vignette("datatable-faq") for background if interested.

