2014-08-31 7 views
3

Скажем, у меня есть два вектора:Вклеивание элементы двух векторов по алфавиту г

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

То, что я хочу сделать, это склеить 1-й, 2-й пары пары, и т.д ..... Тем не менее, я хочу вставьте два элемента каждой пары в алфавитном порядке. В приведенном выше примере первые 2 пары уже в алфавитном порядке, но третья пара «harry» и «chris» не являются. Я хочу вернуть «chris harry» для этой пары.

Я разработал, как это сделать в двухэтапном процессе, но задавался вопросом, был ли быстрый способ (один путь линии), чтобы сделать это, используя только paste?

Мое решение:

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

, который дает пары в алфавитном порядке ... но есть одна линия путь?

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

ответ

3

Вот один подход:

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" 

Использование первой попытки, вы могли бы сделать следующее, но оба они требуют большего набора (не уверен, что о скорости):

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) 
+0

это большое спасибо. Я не мог понять, как включить сортировку в один вкладыш – jalapic

0

Вот аналогичный метод для Тайлера, но с Map. Технически это один лайнер ...

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" 
0

Один лайнер из собственного кода:

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" 
+0

приятно. знаете ли вы, будет ли этот метод быстрее/медленнее, чем метод Тайлера?Я спрашиваю, потому что векторы, которые я спариваю, содержат> 200 000 элементов и вопросы скорости. – jalapic

+0

См. Мое редактирование выше. – rnso

+0

Вы можете использовать system.time() для проверки того, какой из них самый быстрый. Будет интересно узнать результаты, так как многие решения были опубликованы. – rnso

2

немного излишним, поскольку он сортирует в два раза, но vectorised,

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

Edit: альтернатива с ifelse,

ifelse(a < b, paste(a, b), paste(b, a)) 
+0

Это сэр, это хорошо. –

+0

могут быть тонкие проблемы в зависимости от настроек «locale» и т. Д. – baptiste

+0

Я сделал сравнение скорости - этот метод очень быстр! – jalapic

0

Вот сравнение скорости вышеуказанных ответов ...

Я взял данные из моего собственного набора данных всех английских футбольных игр в лиге лучших футбольных 4 деления, можно найти здесь: https://github.com/jalapic/engsoccerdata

Набор данных 'engsoccerdata', и я использовал 3-я и 4-я колонки (домашняя и гостевая команда) для вставки вместе. Я преобразовал каждый столбец в вектор символа. Каждый вектор имеет 188 060 элементов - в верхних 4 ярусах английского футбола с 1888-2014 годов было 188 060 футбольных матчей.

Вот сравнение:

df<-engsoccerdata 

a<-as.character(df[,3]) 
b<-as.character(df[,4]) 

#tyler1 
system.time(apply(cbind(a, b), 1, function(x) paste(sort(x), collapse=" "))) 

#tyler2 
unlist(Map(function(x, y) paste(sort(c(x, y)), collapse=" "), a, b),,FALSE) 

#tyler3 
mapply(function(x, y) paste(sort(c(x, y)), collapse=" "), a, b, USE.NAMES = FALSE) 

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

#baptiste2 
ifelse(a < b, paste(a, b), paste(b, a)) 

#RichardS 
unlist(Map(function(x,y) { 
    paste(sort(c(x,y)), collapse = " ") 
}, a, b, USE.NAMES = FALSE)) 


#rnso1 
apply(data.frame(apply(mapply(c, a, b, USE.NAMES = FALSE),1,paste)),1,function(x) paste(x[1],x[2])) 

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

system.time() Результаты:

#    user system elapsed 
#tyler1  42.92 0.02 43.73 
#tyler2  14.68 0.03 15.04 
#tyler3  14.78 0.00 14.88 
#baptiste1  0.79 0.00 0.84 
#baptiste2  1.25 0.00 1.28 
#RichardS  15.40 0.01 15.64 
#rnso1   6.22 0.10 6.41 
#rnso2  13.07 0.00 13.15 

Очень интересно. Методы баптиста были быстрыми!