Reputation: 3
I want to find the sums (by row) for values within all unique two column combinations in a matrix. For example I want to know V1+V2, therefore I don't need to know V2+V1 and I also don't need V1+V1, V2+V2 and so on.
Using some of the info I have gathered on here, I've been able to create a loop function that partially solves my problem. It sums the values in columns 1 through 4 paired with the values in columns 2 through 5.
set.seed(3)
mydata<-as.data.frame(matrix(rexp(20, rate=.1), ncol=5))
for (i in 1:4) {
for (j in 2:5) {
Newcolname <- paste0(names(mydata)[i],"_",names(mydata)[j])
mydata[[Newcolname]] <- rowSums(mydata[,c(i,j)])
}
}
This code creates what I want but with too much information. I get 16 new columns with sums from columns 1 through 4 paired with columns 2 through 5. This includes redundant information that I'd like to exclude.
Ideally, I'd like to run this function only in cases where j>i so it should create 10 new columns with these sums: V1_V2, V1_V3, V1_V4, V1_V5, V2_V3, V2_4, V2_V5, V3_V4, V3_V5, V4_V5. Thanks for any help. I'm new to creating loop functions.
Upvotes: 0
Views: 38
Reputation: 11150
Here's a way using combn
from base R -
combn(1:ncol(mydata), 2, FUN = function(x) {rowSums(mydata[, x])})
Here's the code with naming. I wonder if there's a better way -
# generate combinations only once; to be used for calculation and naming
combos <- combn(1:ncol(mydata), 2)
# calculate sums for each combo
res <- apply(combos, 2, function(x) {
rowSums(mydata[, x])
})
# set names
colnames(res) <- apply(combos, 2, function(x) paste0("V", x, collapse = "_"))
res
V1_V2 V1_V3 V1_V4 V1_V5 V2_V3 V2_V4 V2_V5
[1,] 19.348279 17.986973 18.88804 21.19083 2.722721 3.623788 5.92658
[2,] 8.238209 7.295317 48.38643 18.24868 3.232870 44.323986 14.18623
[3,] 35.165599 13.101673 18.15211 24.19188 23.608940 28.659382 34.69914
[4,] 10.141323 14.114612 12.03548 27.52704 4.174245 2.095110 17.58667
V3_V4 V3_V5 V4_V5
[1,] 2.262482 4.565274 5.466342
[2,] 43.381094 13.243336 54.334452
[3,] 6.595455 12.635218 17.685659
[4,] 6.068398 21.559962 19.480826
Upvotes: 1