Создайте вектор восходящих и чередующихся элементов из двух переменных длин и уникальных векторов - PullRequest
2 голосов
/ 27 апреля 2019

Объяснение проблемы

Учитывая два вектора переменной длины и без дубликатов между векторами или внутри них, как можно эффективно комбинировать векторы в порядке возрастания и чередования?

Вот пример:

a <- c(98, 101, 104, 136, 154, 193)
b <- c(31, 37, 41, 44, 48, 55, 80, 118, 179)

Ожидаемый вывод

c(31, 98, 118, 136, 179, 193)
# b, a, b, a, b, a

Вы можете видеть, что мы начинаем с 31 от a, наименьшего между векторами. Далее следует 98 из b. Затем из a следующее число, большее 98, равно 118. И так, в результате получается:

A = 98, 136, 193
B = 31, 118, 179

Моя попытка:

x <- c(min(a,b))
lastwas <- startedwithA <- ifelse(x %in% a, 1, 2)

for(i in 1:(length(a)+length(b))){
  if(lastwas == 2){
    x <- c(x, a[which(a > x[i])[1]])
    lastwas <- 1
  } else if(lastwas == 1){
    x <- c(x, b[which(b > x[i])[1]])
    lastwas <- 2
  } 
}
(x <- x[!is.na(x)]) 
# [1]  31  98 118 136 179 193

if(startedwithA == 1){
  evenodd <- c(T,F)
} else {
  evenodd <- c(F,T)
}
(A = x[evenodd]) 
# [1]  98 136 193
(B = x[!evenodd]) 
# [1]  31 118 179

Есть ли лучший способ решить эту проблему?

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

Вы можете установить префиксы имен в соответствии с вектором,

v <- sort(c(setNames(a, paste0("a", a)), setNames(b, paste0("b", b))))

и использовать diff факторизованных начальных символов.

res <- v[!!c(1, diff(as.numeric(as.factor(substr(names(v), 1, 1)))))]
res
# b31  a98 b118 a136 b179 a193 
# 31   98  118  136  179  193

Затем разделить на фрейм данных:

d <- as.data.frame(split(res, substr(names(res), 1, 1)))
d
#        a   b
# a98   98  31
# a136 136 118
# a193 193 179

Данные

a <- c(98, 101, 104, 136, 154, 193)
b <- c(31, 37, 41, 44, 48, 55, 80, 118, 179)
1 голос
/ 27 апреля 2019

Вы можете использовать data.frame, order и diff следующим образом:

a = c(98, 101, 104, 136, 154, 193)
b = c(31, 37, 41, 44, 48, 55, 80, 118, 179)

# Create a data frame for each vector with a different number in column 'set'
dfa = data.frame(val = a, set = 1)
dfb = data.frame(val = b, set = 2)

# Bind both together and order them by val   
df = rbind(dfa,dfb)
df = df[order(df$val),]

# Only keep those that have a diff different to 0
keep = c(1, diff(df$set)) != 0

result = df[keep,]

Результат:

   val set
7   31   2
1   98   1
14 118   2
4  136   1
15 179   2
6  193   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...