Каков эффективный способ выполнения вычислений, которые зависят от выбора различных столбцов, которые индексируются другим столбцом - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь вычесть один столбец из другого, но столбец меняется в зависимости от строки. Это звучит сбивающе с толку, но приведенный ниже пример имеет больше смысла: если у меня есть приведенный ниже фрейм данных (df) ab c d 2 56 14 16 3 89 17 13 2 47 14 19

Я хочу вычислить e, где e равен столбцу b - столбцу с индексом a. Я сделал это, используя для l oop для каждой строки, но это очень медленно:

for(i in 1:nrow(df)){
  df$e <- df$b[i] - df[i, (as.integer(df$a[i]))]
}

df

a  b  c  d  e
2  56 14 16 42
3  89 17 13 76
2  47 14 19 33

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Мы можем использовать индексирование строк / столбцов для векторизации этого

df$e <- df$b - df[-1][cbind(seq_len(nrow(df)), df$a)]
df$e

данных

df <- structure(list(a = c(2L, 3L, 2L), b = c(56L, 89L, 47L), c = c(14L, 
17L, 14L), d = c(16L, 13L, 19L)), class = "data.frame", 
   row.names = c(NA, 
-3L))
0 голосов
/ 06 мая 2020

Не уверен, что это более эффективно, но если вас интересует dplyr + purrr решение ...

library(dplyr)
library(purrr)

df <- structure(list(a = c(2L, 3L, 2L), 
                     b = c(56L, 89L, 47L), 
                     c = c(14L, 17L, 14L), 
                     d = c(16L, 13L, 19L)), 
                class = "data.frame", 
                row.names = c(NA, -3L))


df %>% 
  mutate(e = b - imap_dbl(names(.)[a + 1], ~ pluck(df, .x, .y)))
#>   a  b  c  d  e
#> 1 2 56 14 16 42
#> 2 3 89 17 13 76
#> 3 2 47 14 19 33

Создано 06.05.2020 пакет REPEX (v0.3.0)

...