R 使用映射或函数在数据框中创建新列
我有以下代码,从我已有的汇率中推导出新汇率:R 使用映射或函数在数据框中创建新列,r,dplyr,mapping,purrr,R,Dplyr,Mapping,Purrr,我有以下代码,从我已有的汇率中推导出新汇率: df %>% mutate(ER_AUD_USD = ER_GBP_USD / ER_GBP_AUD, ER_CAD_USD = ER_GBP_USD / ER_GBP_CAD, ER_EUR_USD = ER_GBP_USD / ER_GBP_EUR ) 我可能需要更多,所以我希望有一个函数,可以从货币列表中创建我需要的所有货币。汇率被恰当地命名,因此名称的一部分可以固定 e、 g ER_G
df %>%
mutate(ER_AUD_USD = ER_GBP_USD / ER_GBP_AUD,
ER_CAD_USD = ER_GBP_USD / ER_GBP_CAD,
ER_EUR_USD = ER_GBP_USD / ER_GBP_EUR
)
我可能需要更多,所以我希望有一个函数,可以从货币列表中创建我需要的所有货币。汇率被恰当地命名,因此名称的一部分可以固定
e、 g ER_GBP_USD为英镑/美元,因此:
英镑/美元÷英镑/欧元=英镑/美元×欧元/英镑=欧元/美元
i、 e.ER_***_USD使用您的示例数据,我将首先创建一个函数,该函数基于货币符号创建一个新列
library(tidyverse)
library(rlang)
column_new <- function(data, to_cur, from_cur, mid_cur){
num = sym(paste('ER', mid_cur, to_cur, sep = '_'))
denom = sym(paste('ER', mid_cur, from_cur, sep = '_'))
data = data%>%mutate(!!paste('ER', from_cur, to_cur, sep = '_') := !!num/!!denom)
return(data%>%select(!!sym(paste('ER', from_cur, to_cur, sep = '_'))))
}
并使用purrr::map_dfc
循环我的货币以创建新列
> from_currencies = c('AUD','EUR')
> to_currency = 'CAD'
> df%>%bind_cols(map_dfc(from_currencies, ~column_new(df, to_currency, .x, "GBP")))
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_AUD_CAD ER_EUR_CAD
1 2016-01-01 2.02 2.07 1.11 0.9758454 1.819820
2 2016-02-01 1.99 2.10 1.14 0.9476190 1.745614
3 2016-03-01 1.91 2.06 1.17 0.9271845 1.632479
4 2016-04-01 1.87 2.04 1.13 0.9166667 1.654867
注意:如果要将所有货币作为一个向量循环,请执行以下操作:
currencies = c('AUD','EUR', 'CAD')
valid_column = function(x){
ifelse(is.numeric(x), sum(x) != length(x), TRUE)
}
> df%>%bind_cols(lapply(currencies, function(y) map_dfc(currencies, ~column_new(df,y,.x, "GBP")))%>%bind_cols())%>%select_if(valid_column)
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_EUR_AUD ER_CAD_AUD ER_AUD_EUR
1 2016-01-01 2.02 2.07 1.11 1.864865 1.024752 0.5362319
2 2016-02-01 1.99 2.10 1.14 1.842105 1.055276 0.5428571
3 2016-03-01 1.91 2.06 1.17 1.760684 1.078534 0.5679612
4 2016-04-01 1.87 2.04 1.13 1.805310 1.090909 0.5539216
ER_CAD_EUR ER_AUD_CAD ER_EUR_CAD
1 0.5495050 0.9758454 1.819820
2 0.5728643 0.9476190 1.745614
3 0.6125654 0.9271845 1.632479
4 0.6042781 0.9166667 1.654867
您还可以使用expand.grid
循环所有货币,如下所示:
currencies = c('AUD','EUR', 'CAD')
par_ams <- expand.grid(from_cur = currencies, to_cur = currencies, KEEP.OUT.ATTRS = F, stringsAsFactors = F)%>%filter(from_cur != to_cur)
> df%>%bind_cols(map2(par_ams$from_cur, par_ams$to_cur, ~column_new(df, .x,.y, 'GBP')))
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_AUD_EUR ER_AUD_CAD ER_EUR_AUD
1 2016-01-01 2.02 2.07 1.11 0.5362319 0.9758454 1.864865
2 2016-02-01 1.99 2.10 1.14 0.5428571 0.9476190 1.842105
3 2016-03-01 1.91 2.06 1.17 0.5679612 0.9271845 1.760684
4 2016-04-01 1.87 2.04 1.13 0.5539216 0.9166667 1.805310
ER_EUR_CAD ER_CAD_AUD ER_CAD_EUR
1 1.819820 1.024752 0.5495050
2 1.745614 1.055276 0.5728643
3 1.632479 1.078534 0.6125654
4 1.654867 1.090909 0.6042781
货币=c('AUD'、'EUR'、'CAD')
par_ams%过滤器(从\u cur!=到\u cur)
>df%>%bind_cols(map2(par_ams$from_cur,par_ams$to_cur,~column_new(df,.x,.y,'GBP'))
日期:欧元/加元欧元/加元欧元/加元欧元/加元欧元/加元欧元
1 2016-01-01 2.02 2.07 1.11 0.5362319 0.9758454 1.864865
2 2016-02-01 1.99 2.10 1.14 0.5428571 0.9476190 1.842105
3 2016-03-01 1.91 2.06 1.17 0.5679612 0.9271845 1.760684
4 2016-04-01 1.87 2.04 1.13 0.5539216 0.9166667 1.805310
欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区欧元区
1 1.819820 1.024752 0.5495050
2 1.745614 1.055276 0.5728643
3 1.632479 1.078534 0.6125654
4 1.654867 1.090909 0.6042781
谢谢,循环使用所有这些代码是一种很好的方式,我设计的代码可以在没有交互的情况下工作,但这可能会派上用场。我正在尝试让所有代码都循环使用。什么是df_con
?我得到的对象未找到
。我想缺了一行?应该是有效列
。我编辑了我的代码。我明白了,大概是为了取消选择相同货币的列(即ER\u USD\u USD
,其中只包含1和NAs),我现在得到了以下错误:错误:只有字符串可以转换为符号
我找不到任何关于有效列
如何工作的信息,你知道我能找到什么例子吗?你可以用expand.grid
代替valid\u列
函数。我已经在我的回答中添加了这一点。希望这会给你你想要的。
> from_currencies = c('AUD','EUR')
> to_currency = 'CAD'
> df%>%bind_cols(map_dfc(from_currencies, ~column_new(df, to_currency, .x, "GBP")))
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_AUD_CAD ER_EUR_CAD
1 2016-01-01 2.02 2.07 1.11 0.9758454 1.819820
2 2016-02-01 1.99 2.10 1.14 0.9476190 1.745614
3 2016-03-01 1.91 2.06 1.17 0.9271845 1.632479
4 2016-04-01 1.87 2.04 1.13 0.9166667 1.654867
currencies = c('AUD','EUR', 'CAD')
valid_column = function(x){
ifelse(is.numeric(x), sum(x) != length(x), TRUE)
}
> df%>%bind_cols(lapply(currencies, function(y) map_dfc(currencies, ~column_new(df,y,.x, "GBP")))%>%bind_cols())%>%select_if(valid_column)
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_EUR_AUD ER_CAD_AUD ER_AUD_EUR
1 2016-01-01 2.02 2.07 1.11 1.864865 1.024752 0.5362319
2 2016-02-01 1.99 2.10 1.14 1.842105 1.055276 0.5428571
3 2016-03-01 1.91 2.06 1.17 1.760684 1.078534 0.5679612
4 2016-04-01 1.87 2.04 1.13 1.805310 1.090909 0.5539216
ER_CAD_EUR ER_AUD_CAD ER_EUR_CAD
1 0.5495050 0.9758454 1.819820
2 0.5728643 0.9476190 1.745614
3 0.6125654 0.9271845 1.632479
4 0.6042781 0.9166667 1.654867
currencies = c('AUD','EUR', 'CAD')
par_ams <- expand.grid(from_cur = currencies, to_cur = currencies, KEEP.OUT.ATTRS = F, stringsAsFactors = F)%>%filter(from_cur != to_cur)
> df%>%bind_cols(map2(par_ams$from_cur, par_ams$to_cur, ~column_new(df, .x,.y, 'GBP')))
date ER_GBP_CAD ER_GBP_AUD ER_GBP_EUR ER_AUD_EUR ER_AUD_CAD ER_EUR_AUD
1 2016-01-01 2.02 2.07 1.11 0.5362319 0.9758454 1.864865
2 2016-02-01 1.99 2.10 1.14 0.5428571 0.9476190 1.842105
3 2016-03-01 1.91 2.06 1.17 0.5679612 0.9271845 1.760684
4 2016-04-01 1.87 2.04 1.13 0.5539216 0.9166667 1.805310
ER_EUR_CAD ER_CAD_AUD ER_CAD_EUR
1 1.819820 1.024752 0.5495050
2 1.745614 1.055276 0.5728643
3 1.632479 1.078534 0.6125654
4 1.654867 1.090909 0.6042781