简体   繁体   English

从 R 中的函数或向量在数据框中创建多列

[英]Create multiple columns in dataframe from a function or vector in R

I want to create multiple columns in a dataframe that each calculate a different value based on values from an existing column.我想在数据框中创建多个列,每列都根据现有列中的值计算不同的值。

Say I have the following dataframe:假设我有以下数据框:

date <- c('1','2','3','4','5')
        close <- c('10','20','15','13','19')
        test_df <- data.frame(date,close)

I want to create a new column that does the following operation with dplyr:我想创建一个使用 dplyr 执行以下操作的新列:

test_df %>%
        mutate(logret = log(close / lag(close, n=1)))

However I would like to create a new column for multiple values of n such that I have columns:但是,我想为 n 的多个值创建一个新列,以便我有列:

logret1 for n=1, 
logret2 for n=2, 
logret3 for n=3

etc...等等...

I've used the function seq(from=1, to=5, by=1) as an example to get a vector of numbers to replace n with.我使用函数seq(from=1, to=5, by=1)作为示例来获取一个数字向量来替换 n 。 I've tried to create a for loop around the mutate function:我试图围绕 mutate 函数创建一个 for 循环:

seq2 <- seq(from=1, to=5, by=1)
    
    for (number in seq2){
    new_df <- test_df %>%
      mutate(logret = log(close/lag(close, n=seq2)))
    }

However I get the error:但是我收到错误:

Error: Problem with `mutate()` input `logret`. x `n` must be a nonnegative integer scalar, not a double vector of length 5. i Input `logret` is `log(close2/lag(close2, n = seq2))`.

I realise I can't pass in a vector for n, however I am stuck on how to proceed.我意识到我不能为 n 传递一个向量,但是我被困在如何继续。

Any help would be much appreciated, Thanks.任何帮助将不胜感激,谢谢。

You can use purrr 's map_dfc to add new columns :您可以使用purrrmap_dfc添加新列:

library(dplyr)
library(purrr)

n <- 3
bind_cols(test_df, map_dfc(1:n, ~test_df %>% 
           transmute(!!paste0('logret', .x) := log(close / lag(close, n=.x)))))

#  date close    logret1    logret2     logret3
#1    1    10         NA         NA          NA
#2    2    20  0.6931472         NA          NA
#3    3    15 -0.2876821  0.4054651          NA
#4    4    13 -0.1431008 -0.4307829  0.26236426
#5    5    19  0.3794896  0.2363888 -0.05129329

data数据

test_df <- data.frame(date,close)
test_df <- type.convert(test_df)

You can use data.table .您可以使用data.table It's an R package that provides an enhanced version of data.frame .它是一个 R 包,提供了data.frame的增强版本。 This is an awesome resource to get started with https://www.machinelearningplus.com/data-manipulation/datatable-in-r-complete-guide/这是开始使用https://www.machinelearningplus.com/data-manipulation/datatable-in-r-complete-guide/的绝佳资源

library(data.table)
#Create data.table
test_dt <- data.table(date, close)

#Define the new cols names
logret_cols <- paste0('logret', 1:3)

#Create new columns
test_dt[, (logret_cols) := lapply(1:3, function(n) log(close / lag(close, n = n)))]
test_dt
#   date close    logret1    logret2     logret3
#1:    1    10         NA         NA          NA
#2:    2    20  0.6931472         NA          NA
#3:    3    15 -0.2876821  0.4054651          NA
#4:    4    13 -0.1431008 -0.4307829  0.26236426
#5:    5    19  0.3794896  0.2363888 -0.05129329

data.table has an interesting way to deal with memory efficiently. data.table有一种有趣的方式来有效地处理内存。 If you will deal with large amount of data, take a look at this benchmarks, are awesome: https://h2oai.github.io/db-benchmark/如果你会处理大量数据,看看这个基准测试,很棒: https : //h2oai.github.io/db-benchmark/

EDIT编辑

You can even do it with a mix of data.table and purrr .您甚至可以混合使用data.tablepurrr Here's an example using the function purrr::map()这是使用函数purrr::map()的示例

test_dt[, (logret_cols) := map(1:3, ~log(close / lag(close, n = .x)))]
test_dt
#   date close    logret1    logret2     logret3
#1:    1    10         NA         NA          NA
#2:    2    20  0.6931472         NA          NA
#3:    3    15 -0.2876821  0.4054651          NA
#4:    4    13 -0.1431008 -0.4307829  0.26236426
#5:    5    19  0.3794896  0.2363888 -0.05129329

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM