Search code examples
runiquetidyversedplyr

Aggregating interaction patterns between partners


Research context: 'Listener' posts their thoughts and 'speaker' reacts to the listener. The first observed listener for each thread is the original post writer.

Example data:

structure(list(topic = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2), thread = c(1, 
1, 1, 2, 2, 2, 3, 3, 3, 3, 3), listener_id = c(111, 111, 333, 
222, 222, 222, 444, 444, 777, 444, 444), speaker_id = c(222, 
333, 111, 111, 555, 444, 222, 777, 444, 333, 777), speaker_response = c(3, 
3, 6, 1, 4, 4, 4, 2, 2, 5, 3)), class = "data.frame", row.names = c(NA, 
-11L), codepage = 65001L)

In a table, it looks like:

╔═══════╦════════╦═════════════╦════════════╦══════════════════╗
║ topic ║ thread ║ listener_id ║ speaker_id ║ speaker_response ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    1   ║     111     ║     222    ║         3        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    1   ║     111     ║     333    ║         3        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    1   ║     333     ║     111    ║         6        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    2   ║     222     ║     111    ║         1        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    2   ║     222     ║     555    ║         4        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  1.00 ║    2   ║     222     ║     444    ║         4        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  2.00 ║    3   ║     444     ║     222    ║         4        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  2.00 ║    3   ║     444     ║     777    ║         2        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║ 2.00  ║    3   ║     777     ║     444    ║         2        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║ 2.00  ║    3   ║     444     ║     333    ║         5        ║
╠═══════╬════════╬═════════════╬════════════╬══════════════════╣
║  2.00 ║    3   ║     111     ║     777    ║         3        ║
╚═══════╩════════╩═════════════╩════════════╩══════════════════╝

The aim is:

  • Aggregate by the first listener of each thread within a topic regarding speakers' (other than the focal listener's response made in turn) average response quality.

This may be confusing in words; to visualize, the end result looks like:

╔═══════╦════════╦═════════════╦═════════════════╦══════════════════════════════════════════╗
║ topic ║ thread ║ listener_id ║ others_response ║                explanation               ║
╠═══════╬════════╬═════════════╬═════════════════╬══════════════════════════════════════════╣
║   1   ║    1   ║     111     ║        3        ║ Here, the first listener was 111         ║
║       ║        ║             ║                 ║ and others' average response = (3+3)/2,  ║
║       ║        ║             ║                 ║ excluding the last observation where 111 ║
║       ║        ║             ║                 ║ was the speaker.                         ║
╠═══════╬════════╬═════════════╬═════════════════╬══════════════════════════════════════════╣
║   1   ║    2   ║     222     ║        3        ║                                          ║
╠═══════╬════════╬═════════════╬═════════════════╬══════════════════════════════════════════╣
║   2   ║    3   ║     444     ║       3.5       ║ Excluding the response made by the first ║
║       ║        ║             ║                 ║ listener, the average is (4+2+5+3)/4.    ║
╚═══════╩════════╩═════════════╩═════════════════╩══════════════════════════════════════════╝

Solution

  • You can remove those responses whose speaker_id is equal to first listener_id and mean the speaker_response value for each topic and thread.

    library(dplyr)
    
    df %>%
      group_by(topic, thread) %>%
      summarise(others_response = mean(speaker_response[speaker_id != first(listener_id)]), 
                listener_id = first(listener_id))
    
    #  topic thread others_response listener_id
    #  <dbl>  <dbl>           <dbl>       <dbl>
    #1     1      1             3           111
    #2     1      2             3           222
    #3     2      3             3.5         444