Как создать несколько новых групповых переменных наиболее эффективно? - PullRequest
0 голосов
/ 26 ноября 2018

Давайте использовать следующий пример:

set.seed(2409)
N=5
T=10
id<- rep(LETTERS[1:N],each=T)
time<-rep(1:T, times=N)
var1<-runif(N*T,0,100)
var2<-runif(N*T,0,100)
var3<-runif(N*T,0,100)
var4<-runif(N*T,0,100)
var5<-runif(N*T,0,100)
df<-data.frame(id,time,var1,var2,var3,var4,var5); rm(N,T,id,time,var1,var2,var3,var4,var5)

Теперь я попытаюсь выполнить функцию для нескольких из этих переменных (а не всего ряда переменных!) И соответственно создать новые переменные.

У меня уже есть подходящий код для создания переменных журнала.Для этого я бы использовал следующий код:

cols <- c("var1", 
          "var3",
          "var5")
log <- log(df[cols])
colnames(log) <- paste(colnames(log), "log", sep = "_")
df <- cbind(df,log); rm(log, cols)

Это дало бы мне дополнительные журнальные переменные.Но теперь я также хочу создать лаговые и z-преобразованные переменные.Эти функции относятся к отдельным идентификаторам.Поэтому я написал следующий код, который, конечно, работает, но он очень длинный и неэффективный в моем реальном наборе данных, где я применяю функцию к 38 переменным каждая:

library(Hmisc)
library(dplyr)
df<-df %>%
  group_by(id) %>%
  mutate(var1_1=Lag(var1, shift=1),
         var3_1=Lag(var3, shift=1),
         var5_1=Lag(var5, shift=1),
         var1_2=Lag(var1, shift=2),
         var3_2=Lag(var3, shift=2),
         var5_2=Lag(var5, shift=2),
         var1_z=scale(var1),
         var3_z=scale(var3),
         var5_z=scale(var5)
         )

Я очень уверен, что есть и способчтобы сделать это более эффективным.Было бы желательно, если бы я мог определить исходную переменную один раз, выполнить разные функции и в результате создать новые переменные.

Большое спасибо!

Ответы [ 2 ]

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

Вот вариант с data.table

library(data.table)
nm1 <- c('var1', 'var3', 'var5')
nm2 <- paste0(nm1, rep(c('_lag1', '_lag2'), each = 3))
nm3 <- paste0(nm1, '_scale')
setDT(df)[, c(nm2, nm3) := c(shift(.SD, n = 1:2), lapply(.SD, 
          function(x) as.vector(scale(x)))), by = id, .SDcols = nm1]'
0 голосов
/ 26 ноября 2018

Вы можете использовать mutate_at с funs.Это позволит применить три функции в funs к каждой из трех переменных в vars, создав 9 новых столбцов.

library(dplyr)

df %>%
  group_by(id) %>%
  mutate_at(vars(var1, var3, var5),
            funs(lag1 = lag(.), lag2 = lag(., 2), scale))

# # A tibble: 50 x 16
# # Groups:   id [5]
#    id     time   var1  var2   var3  var4  var5 var1_lag1 var3_lag1 var5_lag1
#    <fct> <int>  <dbl> <dbl>  <dbl> <dbl> <dbl>     <dbl>     <dbl>     <dbl>
#  1 A         1 38.8   25.7  29.2    91.1  35.3    NA        NA          NA  
#  2 A         2 87.1   22.3   8.27   31.5  93.7    38.8      29.2        35.3
#  3 A         3 61.7   38.8   0.887  63.0  50.4    87.1       8.27       93.7
#  4 A         4  0.692 60.1  71.5    74.0  41.6    61.7       0.887      50.4
#  5 A         5 60.1   13.3  90.4    80.6  47.5     0.692    71.5        41.6
#  6 A         6 46.4    3.67 36.7    86.9  67.5    60.1      90.4        47.5
#  7 A         7 80.4   72.1  82.2    25.5  70.3    46.4      36.7        67.5
#  8 A         8 48.8   25.7  93.4    19.8  81.2    80.4      82.2        70.3
#  9 A         9 48.2   31.5  82.1    47.2  49.2    48.8      93.4        81.2
# 10 A        10 21.8   32.6  76.5    19.7  41.1    48.2      82.1        49.2
# # ... with 40 more rows, and 6 more variables: var1_lag2 <dbl>, var3_lag2 <dbl>,
# #   var5_lag2 <dbl>, var1_scale <dbl>, var3_scale <dbl>, var5_scale <dbl>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...