Как мне создать новые переменные на основе сравнения двухсимвольных переменных без использования вложенной функции цикла? - PullRequest
2 голосов
/ 17 октября 2019

Как избежать вложенных циклов в R: Как создать новые переменные на основе сравнения двухсимвольных переменных без использования вложенных циклических функций?

Например, у меня есть две символьные переменные A и B:

A=c("yellow","orange","dog","dog","green","heaven","tree") #searchspace
B=c("dog","house","tree","yellow","dog","road","hell","rain","dog","tree") # target labels

Для каждого элемента в пространстве поиска (A) я хочу:

  1. подсчитать, сколько раз элемент присутствует в списке (B) и,
  2. если присутствует, в какой позиции он был впервые найден в списке B и,
  3. , если присутствует в нескольких позициях в B, какая позиция была последней в списке B.
  4. сохранить выходные данные(1), (2) и (3) в data.table, включая список A.

Вывод будет выглядеть примерно так:

       A totcount firstindex lastindex
1: yellow        1          4         0
2: orange        0          0         0
3:    dog        3          1         9
4:    dog        3          1         9
5:  green        0          0         0
6: heaven        0          0         0
7:   tree        2          3        10

Я написалвложенная в функцию цикла, чтобы выполнить это, но это действительно медленно с списками A и B, имеющими более 16k и 2K элементов каждый, соответственно. Я изо всех сил пытался использовать функции применения, чтобы решить эту проблему.

Любые предложения будут высоко оценены. Спасибо

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Базовый раствор R:

A <- c("yellow", "orange", "dog", "dog", "green", "heaven", "tree")
B <- c("dog", "house", "tree", "yellow", "dog", "road", "hell", "rain",
       "dog", "tree")

X <- sapply(A, function(a) {
    totcount <- sum(B %in% a)
    firstindex <- ifelse(totcount > 0, min(which(B %in% a)), 0)
    lastindex <- ifelse(totcount > 1, max(which(B %in% a)), 0)
    c(totcount=totcount, firstindex=firstindex, lastindex=lastindex)
})

> t(X)
       totcount firstindex lastindex
yellow        1          4         0
orange        0          0         0
dog           3          1         9
dog           3          1         9
green         0          0         0
heaven        0          0         0
tree          2          3        10
1 голос
/ 17 октября 2019

Вы можете просто поместить A во фрейм данных и использовать dplyr для вычисления без использования apply.

library(dplyr)

df <- as.data.frame(A)

df %>%
  group_by(A) %>%
  mutate(totcount = sum(B %in% A),
         firstindex = ifelse(totcount > 0, min(which(B %in% A)), 0),
         lastindex = ifelse(totcount > 1, max(which(B %in% A)), 0))

#> # A tibble: 7 x 4
#> # Groups:   A [6]
#>   A      totcount firstindex lastindex
#>   <fct>     <int>      <dbl>     <dbl>
#> 1 yellow        1          4         0
#> 2 orange        0          0         0
#> 3 dog           3          1         9
#> 4 dog           3          1         9
#> 5 green         0          0         0
#> 6 heaven        0          0         0
#> 7 tree          2          3        10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...