C ++ или Rcpp: сравнение двух векторов без цикла - PullRequest
0 голосов
/ 18 апреля 2019

Я новичок в C ++ и Rcpp, и мне интересно, как сравнивать каждый элемент двух разных векторов без цикла одновременно.

Моя цель - изменить элемент v1 путем ссылкидругой вектор.

Текущий код:

v1 = {6,7,8,9,10}
v2 = {2,4,6,8,10}
v3 = {a,b,a,b,c}
v4 = {0,0,0,0,0}
v5 = {a,b,c}
v6 = {1,2,3}

for (i in 1:5){
  if (v1[i] > v2[i]){
    for (j in 1:3){
      if (v5[j] == v3[i]){
        v4[i] = v2[i] + v6[j]
          if (v1[i] > v4[i]){
            v1[i] = v4[i]
          }
      }
    }
  }
}  

Результат может быть

v1 = {3,6,7,9,10}

На самом деле v1, v2, v3, v4 и v5, v6 - это разные dataframe в R. Каждый элемент v1 сравнивается с v2.Если элемент i в v1 больше, чем i элемент в v2, элемент v1 становится суммой i элемента v1 и элемента v6 на соответствующий v3 & v5.Затем вновь оцененное значение v4[i] сравнивается с v1[i].

У меня большое количество случаев в v1~v5 и v5~v6.В этом случае использование loop занимает много времени.Можно ли сравнить разные векторы без петли?или как оценить и ссылаться на элемент другого вектора?

1 Ответ

2 голосов
/ 18 апреля 2019

Я не вижу необходимости использовать Rcpp или C ++ здесь. Насколько я понимаю ваши требования, вы пытаетесь манипулировать двумя наборами векторов одинаковой длины. Для «набора равной длины» векторов обычно используют data.frame или одно из его расширений. Здесь я использую базы R, data.table и dplyr с tibble. Посмотрите сами, какой синтаксис вы предпочитаете. Вообще говоря, data.table, скорее всего, будет быстрее для больших наборов данных.

Данные настройки:

v1 <- c(6,7,8,9,10)
v2 <- c(2,4,6,8,10)
v3 <- c("a","b","a","b","c")
v5 <- c("a","b","c")
v6 <- c(1,2,3)

База R:

df1 <- data.frame(v1, v2, v3)
df2 <- data.frame(v5, v6)

df1 <- merge(df1, df2, by.x = "v3", by = "v5")
df1$v4 <- df1$v2 + df1$v6
df1$v1 <- ifelse(df1$v1 > df1$v2 & df1$v1 > df1$v4, df1[["v4"]], df1[["v1"]])
df1
#>   v3 v1 v2 v6 v4
#> 1  a  3  2  1  3
#> 2  a  7  6  1  7
#> 3  b  6  4  2  6
#> 4  b  9  8  2 10
#> 5  c 10 10  3 13

data.table:

library(data.table)
dt1 <- data.table(v1, v2, v3, key = "v3")
dt2 <- data.table(v5, v6, key = "v5")

dt1[dt2, v4 := v2 + v6]
dt1[v1 > v2 & v1 > v4, v1 := v4]
dt1
#>    v1 v2 v3 v4
#> 1:  3  2  a  3
#> 2:  7  6  a  7
#> 3:  6  4  b  6
#> 4:  9  8  b 10
#> 5: 10 10  c 13

dplyr

suppressPackageStartupMessages(library(dplyr))
t1 <- tibble(v1, v2, v3)
t2 <- tibble(v5, v6)
t1 %>% 
  inner_join(t2, by = c("v3" = "v5")) %>%
  mutate(v4 = v2 + v6) %>%
  mutate(v1 = case_when(
    v1 > v2 & v1 > v4 ~ v4,
    TRUE ~ v1
  ))
#> # A tibble: 5 x 5
#>      v1    v2 v3       v6    v4
#>   <dbl> <dbl> <chr> <dbl> <dbl>
#> 1     3     2 a         1     3
#> 2     6     4 b         2     6
#> 3     7     6 a         1     7
#> 4     9     8 b         2    10
#> 5    10    10 c         3    13

Создано в 2019-04-19 пакетом представ (v0.2.1)

Общая идея всегда одна и та же:

  • объединить две таблицы в столбце символов
  • создать новый столбец v4 как сумму v2 и v6
  • обновить v1 до значения v4, где v1 > v2 и v1 > v4

Обратите внимание, что базы R и data.table не сохраняют порядок, поэтому было бы разумнее поместить вывод в дополнительный столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...