簡體   English   中英

使用dplyr :: mutate將函數的參數化應用於單個數據框列,然后將結果保存到新列?

[英]Using dplyr::mutate to apply parameterizations of a function to a single data frame column, then save the results to new columns?

假設我有一個看起來像這樣的數據框:

user_id  date          weight
12345    2016-03-07    160
12345    2016-03-06    158
12345    2016-03-05    156
12345    2016-03-04    154

我想通過將多個功能應用於weight列,然后將每個應用程序的結果保存到一個新列中來對該數據框進行更改。 一個警告是該函數已參數化,我想將參數值附加到新的列名上。 例如,如果我使用lag()

user_id  date          weight    dweight_1    dweight_2    ...
12345    2016-03-07    160       NA           NA   
12345    2016-03-06    158       160          NA
12345    2016-03-05    156       158          160
12345    2016-03-04    154       156          158

其中第一列是lag(weight, 1)的結果,第二列是lag(weight, 2) ,依此類推。

我嘗試遵循dplyr插圖中針對該主題提出的標准評估方法以及該SO問題的建議,但似乎都無法解決參數化函數的問題(否則,我只會使用funs() !)。

我該如何解決這個問題?

要使用dplyr編程方式添加單個列,您可以使用類似

x <- 2
mutate_(df, .dots = setNames(list(~lag(weight, x)), paste0('dweight_', x)))

如果只是幾次(如果願意,甚至可以將它們鏈接在一起),您可以重復一遍,但是如果您經常這樣做,那么編寫一個函數可能很有意義:

dweight <- function(l = 1){
  for (i in l){
    df <- mutate_(df, .dots = setNames(list(~lag(weight, i)), paste0('dweight_', i)))
  }
  df
}

您可以傳遞向量:

> dweight(1:4)
  user_id       date weight dweight_1 dweight_2 dweight_3 dweight_4
1   12345 2016-03-07    160        NA        NA        NA        NA
2   12345 2016-03-06    158       160        NA        NA        NA
3   12345 2016-03-05    156       158       160        NA        NA
4   12345 2016-03-04    154       156       158       160        NA

您可以根據需要編輯該函數:添加一個dataframe參數,以便可以鏈接它,使用*apply代替for ,添加參數以傳遞函數,等等。

這是一個應該起作用的解決方案(盡管可能有更清潔的方法)

# Assuming lag_vals is set as follows
lag_vals <- 1:3
names(lag_vals) <- paste0('dweight_', 1:3)

df_new <- cbind(df, sapply(lag_vals, function(x) { x=lag(df$weight, x) }))
df_new
##   user_id       date weight dweight_1 dweight_2 dweight_3
## 1   12345 2016-03-07    160        NA        NA        NA
## 2   12345 2016-03-06    158       160        NA        NA
## 3   12345 2016-03-05    156       158       160        NA
## 4   12345 2016-03-04    154       156       158       160

帶有標准評估的dplyr :: mutate解決方案:

tab %>% mutate_(.dots = setNames(lapply(1:4, function(i) lazyeval::interp(~lag(weight, i),
        weight = as.name("weight"))), paste0("weight_", 1:4)))
#   user_id       date weight weight_1 weight_2 weight_3 weight_4
# 1   12345 2016-03-07    160       NA       NA       NA       NA
# 2   12345 2016-03-06    158      160       NA       NA       NA
# 3   12345 2016-03-05    156      158      160       NA       NA
# 4   12345 2016-03-04    154      156      158      160       NA

編輯:這有點整理...

lags = 3
lag_weight <- function(i) lazyeval::interp(~lag(weight, i), weight = as.name("weight"))
tab %>% mutate_(.dots = setNames(lapply(1:lags, lag_weight), paste0('weight_', 1:lags)))
#   user_id       date weight weight_1 weight_2 weight_3 weight_4
# 1   12345 2016-03-07    160       NA       NA       NA       NA
# 2   12345 2016-03-06    158      160       NA       NA       NA
# 3   12345 2016-03-05    156      158      160       NA       NA
# 4   12345 2016-03-04    154      156      158      160       NA

您可以使用tidyquant::tq_mutate解決此問題。 這是一個玩具示例。

# Get Stock Prices from Yahoo! Finance

# Create a vector of stock symbols
FANG_symbols <- c("FB", "AMZN", "NFLX", "GOOG")

# Pass symbols to tq_get to get daily prices
FANG_data_d <- FANG_symbols %>%
    tq_get(get = "stock.prices", from = "2014-01-01", to = "2016-12-31")

# Show the result
FANG_data_d

FANG_data_d %>%
    select(symbol, date, adjusted) %>%
    group_by(symbol) %>%
    tq_mutate(
        select     = adjusted,
        mutate_fun = lag.xts,
        k          = 1:5,
        col_rename = column_names
    )

參考

丹喬,馬特。 2017年。“演示周:課程(星期一)<-Tidyquant。” http://www.business-science.io/code-tools/2017/10/23/demo_week_tidyquant.html

暫無
暫無

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

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