簡體   English   中英

使用dplyr mutate自動生成新變量名

[英]Automatically generate new variable names using dplyr mutate

我想在使用dplyr時動態創建變量名; 雖然,我也可以使用非dplyr解決方案。

例如:

data(iris)
library(dplyr) 

iris <- iris %>%
  group_by(Species) %>%
  mutate(
    lag_Sepal.Length = lag(Sepal.Length),
    lag_Sepal.Width  = lag(Sepal.Width),
    lag_Petal.Length = lag(Petal.Length)
  ) %>%
  ungroup

head(iris)

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species lag_Sepal.Length lag_Sepal.Width
             (dbl)       (dbl)        (dbl)       (dbl)  (fctr)            (dbl)           (dbl)
    1          5.1         3.5          1.4         0.2  setosa               NA              NA
    2          4.9         3.0          1.4         0.2  setosa              5.1             3.5
    3          4.7         3.2          1.3         0.2  setosa              4.9             3.0
    4          4.6         3.1          1.5         0.2  setosa              4.7             3.2
    5          5.0         3.6          1.4         0.2  setosa              4.6             3.1
    6          5.4         3.9          1.7         0.4  setosa              5.0             3.6
    Variables not shown: lag_Petal.Length (dbl)

但是,我想創建100個這樣的“滯后”變量,而不是這樣做三次,這些變量的名稱為:lag_original variable name。 我試圖弄清楚如何在不輸入新變量名100次的情況下做到這一點,但我現在做得很短。

我在SO的其他地方研究了這個例子和這個例子。 它們是相似的,但我不能完全拼湊我需要的具體解決方案。 任何幫助表示贊賞!

編輯
感謝@BenFasoli的靈感。 我接受了他的回答並稍微調整了一下以獲得我需要的解決方案。 我也使用了這個RStudio博客這個SO帖子 變量名中的“滯后”是尾隨而不是前導,但我可以忍受。

我的最終代碼發布在這里,以防它對其他人有幫助:

lagged <- iris %>%
  group_by(Species) %>%
  mutate_at(
    vars(Sepal.Length:Petal.Length),
    funs("lag" = lag)) %>%
  ungroup

# A tibble: 6 x 8
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_lag Sepal.Width_lag
         <dbl>       <dbl>        <dbl>       <dbl>  <fctr>            <dbl>           <dbl>
1          5.1         3.5          1.4         0.2  setosa               NA              NA
2          4.9         3.0          1.4         0.2  setosa              5.1             3.5
3          4.7         3.2          1.3         0.2  setosa              4.9             3.0
4          4.6         3.1          1.5         0.2  setosa              4.7             3.2
5          5.0         3.6          1.4         0.2  setosa              4.6             3.1
6          5.4         3.9          1.7         0.4  setosa              5.0             3.6
# ... with 1 more variables: Petal.Length_lag <dbl>

您可以使用mutate_all (或mutate_at用於特定列),然后將lag_到列名稱之前。

data(iris)
library(dplyr) 

lag_iris <- iris %>%
  group_by(Species) %>%
  mutate_all(funs(lag(.))) %>%
  ungroup
colnames(lag_iris) <- paste0('lag_', colnames(lag_iris))

head(lag_iris)

  lag_Sepal.Length lag_Sepal.Width lag_Petal.Length lag_Petal.Width lag_Species
             <dbl>           <dbl>            <dbl>           <dbl>      <fctr>
1               NA              NA               NA              NA      setosa
2              5.1             3.5              1.4             0.2      setosa
3              4.9             3.0              1.4             0.2      setosa
4              4.7             3.2              1.3             0.2      setosa
5              4.6             3.1              1.5             0.2      setosa
6              5.0             3.6              1.4             0.2      setosa

這是一個data.table方法。 在這種情況下,我選擇了帶數字的列。 您要做的是提前選擇列名並創建新列名。 然后,將shift()類似於dplyr包中的lag()lead()應用於您選擇的每個列。

library(data.table)

# Crate a df for this demo.
mydf <- iris

# Choose columns that you want to apply lag() and create new colnames.
cols = names(iris)[sapply(iris, is.numeric)]
anscols = paste("lag_", cols, sep = "")

# Apply shift() to each of the chosen columns.
setDT(mydf)[, (anscols) := shift(.SD, 1, type = "lag"),
            .SDcols = cols]

     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species lag_Sepal.Length lag_Sepal.Width
 1:          5.1         3.5          1.4         0.2    setosa               NA              NA
 2:          4.9         3.0          1.4         0.2    setosa              5.1             3.5
 3:          4.7         3.2          1.3         0.2    setosa              4.9             3.0
 4:          4.6         3.1          1.5         0.2    setosa              4.7             3.2
 5:          5.0         3.6          1.4         0.2    setosa              4.6             3.1
 ---                                                                                             
146:          6.7         3.0          5.2         2.3 virginica              6.7             3.3
147:          6.3         2.5          5.0         1.9 virginica              6.7             3.0
148:          6.5         3.0          5.2         2.0 virginica              6.3             2.5
149:          6.2         3.4          5.4         2.3 virginica              6.5             3.0
150:          5.9         3.0          5.1         1.8 virginica              6.2             3.4
     lag_Petal.Length lag_Petal.Width
  1:               NA              NA
  2:              1.4             0.2
  3:              1.4             0.2
  4:              1.3             0.2
  5:              1.5             0.2
 ---                                 
146:              5.7             2.5
147:              5.2             2.3
148:              5.0             1.9
149:              5.2             2.0
150:              5.4             2.3

既然你對非dplyr感到滿意,試試這個:

lagger <- function(x, n) c(rep(NA,n), head(x,-n) )
iris[paste0("lag_", names(iris) )] <- lapply(iris, lagger, n=1)

head(iris,2)[-(1:5)]
#  lag_Sepal.Length lag_Sepal.Width lag_Petal.Length lag_Petal.Width lag_Species
#1               NA              NA               NA              NA          NA
#2              5.1             3.5              1.4             0.2           1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM