Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pasting elements of two vectors alphabetically

Say I have two vectors:

a <- c("george", "harry", "harry", "chris", "steve", "steve", "steve", "harry")
b <- c("harry", "steve", "chris", "harry", "harry", "george", "chris", "george")

What I want to do is paste together the 1st pair, 2nd pair, etc..... However, I want to paste the two elements of each pair in alphabetical order. In the above example, the first 2 pairs are already in alphabetical order, but the 3rd pair 'harry' and 'chris' are not. I want to return "chris harry" for this pair.

I have worked out how to do this in a 2 step process, but was wondering if there was a quick way (one line way) to do this just using paste?

My solution:

x <- apply(mapply(c, a, b, USE.NAMES = FALSE), 2, sort)
paste(x[1,], x[2,])

which gives the pairs in alphabetical order... but is there a 1 line way?

[1] "george harry" "harry steve"  "chris harry"  "chris harry"  "harry steve"  "george steve" "chris steve"  "george harry"
like image 239
jalapic Avatar asked Aug 31 '14 02:08

jalapic


4 Answers

slightly redundant because it sorts twice, but vectorised,

paste(pmin(a,b), pmax(a,b))

Edit: alternative with ifelse,

ifelse(a < b, paste(a, b), paste(b, a))
like image 190
baptiste Avatar answered Sep 16 '22 16:09

baptiste


Here's one approach:

apply(cbind(a, b), 1, function(x) paste(sort(x), collapse=" "))

## [1] "george harry" "harry steve"  "chris harry"  "chris harry"  
## [5] "harry steve" "george steve" "chris steve"  "george harry"

Using your initial attempt, you could also do the following but they both require more typing (not sure about speed):

unlist(Map(function(x, y) paste(sort(c(x, y)), collapse=" "), a, b),,FALSE)
mapply(function(x, y) paste(sort(c(x, y)), collapse=" "), a, b, USE.NAMES = FALSE)
like image 33
Tyler Rinker Avatar answered Sep 18 '22 16:09

Tyler Rinker


One liner from your own code:

apply(data.frame(apply(mapply(c, a, b, USE.NAMES = FALSE),1,paste)),1,function(x) paste(x[1],x[2]))
[1] "george harry" "harry steve"  "harry chris"  "chris harry"  "steve harry"  "steve george" "steve chris"  "harry george"


apply(apply(mapply(c, a, b, USE.NAMES = FALSE),2,sort),1,paste)

     [,1]     [,2]   
[1,] "george" "harry"
[2,] "harry"  "steve"
[3,] "chris"  "harry"
[4,] "chris"  "harry"
[5,] "harry"  "steve"
[6,] "george" "steve"
[7,] "chris"  "steve"
[8,] "george" "harry"
like image 42
rnso Avatar answered Sep 17 '22 16:09

rnso


Here's a similar method to Tyler's, but with Map. Technically it's a one-liner...

unlist(Map(function(x,y) {
    paste(sort(c(x,y)), collapse = " ")
    }, a, b, USE.NAMES = FALSE))
# [1] "george harry" "harry steve"  "chris harry"  "chris harry" 
# [5] "harry steve"  "george steve" "chris steve"  "george harry"
like image 26
Rich Scriven Avatar answered Sep 18 '22 16:09

Rich Scriven