I have a list of named vectors. I am trying to sum their values. But some of the names within a vector have reversed equivalents. For example, if I have some data that looks like this:
myList <- list(`1` = c('x1:x2' = 2, 'x2:x1' = 1, 'x3:x4' = 1),
`2` = c('x1:x2' = 3, 'x6:x1' = 2, 'x1:x1' = 1, 'x4:x3' = 1),
`3` = c('x3:x4' = 2, 'x1:x2' = 1, 'x4:x3' = 4),
`4` = c('x5:x2' = 1, 'x2:x5' = 1)
)
> myList
$`1`
x1:x2 x2:x1 x3:x4
2 1 1
$`2`
x1:x2 x6:x1 x1:x1 x4:x3
3 2 1 1
$`3`
x3:x4 x1:x2 x4:x3
2 1 4
$`4`
x5:x2 x2:x5
1 1
Here, we can see that in myList[[1]]
we have x1:x2 = 2
and x2:x1 = 1
. As these are the reverse of each other, they are equivalent, so, essentially, x1:x2 = 3
.
I am trying to sum the values for each named element (including the reverse) over each list element.
My desired output would look something like this:
var count listNo
1 x1:x2 3 1
2 x3:x4 1 1
3 x1:x2 3 2
4 x6:x1 2 2
5 x1:x1 1 2
6 x4:x3 1 2
7 x3:x4 6 3
8 x1:x2 1 3
9 x5:x2 2 4
This is tricky. I'd be interested to see a more elegant solution
`row.names<-`(do.call(rbind, Map(function(vec, name) {
x <- names(vec)
l <- sapply(strsplit(x, ":"), function(y) {
paste0("x", sort(as.numeric(sub("\\D", "", y))), collapse = ":")
})
df <- setNames(as.data.frame(table(rep(l, vec))), c("var", "count"))
df$listNo <- name
df
}, vec = myList, name = names(myList))), NULL)
#> var count listNo
#> 1 x1:x2 3 1
#> 2 x3:x4 1 1
#> 3 x1:x1 1 2
#> 4 x1:x2 3 2
#> 5 x1:x6 2 2
#> 6 x3:x4 1 2
#> 7 x1:x2 1 3
#> 8 x3:x4 6 3
#> 9 x2:x5 2 4
Created on 2022-03-06 by the reprex package (v2.0.1)
Another tidyverse
option could be:
map_dfr(myList, enframe, .id = "listNo") %>%
mutate(var = map_chr(str_split(name, ":"), ~ str_c(sort(.), collapse = ":"))) %>%
group_by(listNo, var) %>%
summarise(count = sum(value))
listNo var count
<chr> <chr> <dbl>
1 1 x1:x2 3
2 1 x3:x4 1
3 2 x1:x1 1
4 2 x1:x2 3
5 2 x1:x6 2
6 2 x3:x4 1
7 3 x1:x2 1
8 3 x3:x4 6
9 4 x2:x5 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With