如何最有效地创建几个新的基于组的变量?

时间:2018-11-26 14:50:46

标签: r

让我们使用以下示例:

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转换的变量。这些功能引用各个ID。因此,我编写了下面的代码,这些代码当然可以用,但是在我将函数分别应用于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 :(得分:1)

您可以将mutate_atfuns一起使用。这会将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>

答案 1 :(得分:0)

这里是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]'