Вложенные пользовательские функции с использованием apply в R - PullRequest
0 голосов
/ 30 октября 2018

Как будет написано следующее с использованием apply?

# Variables
age <- 1:100
Y   <- age+5
d   <- 0.25
dx  <- 5
a_x <- 1:dx
Yd  <- matrix( 0, nrow=max(age), ncol=dx )

# Nested loop is computationally inefficient?
for (a in age){
  for (ax in a_x){
    Yd[a,ax] <- (Y[[a]] * (1 - d) ** (ax-1))
  }
}

У моей модели много таких вложенных в петлевые структуры, потому что я некомпетентен. Я надеюсь улучшить вычислительное время с помощью apply. Я нахожу функции применения довольно запутанными, чтобы войти в. Я ищу решение, которое иллюстрирует, как можно получить такие вложенные структуры, используя apply. Надеюсь, что с этого момента я смогу применить (каламбур) решение для еще более сложных вложенных циклов (4-5 циклов внутри друг друга).

Например

Ydi <- rep( list(), 6)

for (i in 1:6){
  Ydi[[i]] <- matrix( 0, nrow=max(age), ncol=dx )
}

# Nested loop is computationally inefficient?
for (i in 1:6){
  for (a in age){
    for (ax in a_x){
      Ydi[[i]][a,ax] <- (Y[[a]] * (1 - d) ** (ax-1)) + i
    }
  }
}

1 Ответ

0 голосов
/ 19 ноября 2018

Я бы использовал expand.grid вместо:

df <- data.frame(expand.grid(a = age, ax = a_x))
df[['Yd']] <- (df[['a']] + 5) * (1 - d) ** (df[['ax']] - 1)

Это бесконечно расширяемое (с учетом ограничений памяти) - каждый дополнительный вложенный цикл будет просто дополнительной переменной в вашем вызове expand.grid. Например:

new_col <- 1:2
df_2 <- data.frame(expand.grid(a = age, ax = a_x, nc = new_col))
df_2[['Yd']] <- (df_2[['a']] + 5) * (1 - d) ** (df_2[['ax']] - 1) + df_2[['nc']]

По сути, это переключается на формат аккуратные данные , который является более простым способом хранения многомерных данных.

Для упрощения синтаксиса и повышения скорости вы можете использовать пакет data.table:

library(data.table)
dt_3 <- data.table(expand.grid(a = age, ax = a_x, nc = new_col))
dt_3[ , Yd := (a + 5) * (1 - d) ** (ax - 1) + nc]
...