在数据框中的特定位置添加列的优雅方式
Elegant way of adding columns on a specific position in a data frame
我有一个包含 3 列的 data.frame:日期、费率、价格。我想在费率之后和价格之前添加来自矩阵的列。
df = tibble('date' = c('01/01/2000', '02/01/2000', '03/01/2000'),
'rate' = c(7.50, 6.50, 5.54),
'price' = c(92, 94, 96))
我使用输出矩阵的函数计算了速率的滞后:
rate_Lags = matrix(data = c(NA, 7.50, 5.54, NA, NA, 7.50), ncol=2, dimnames=list(c(), c('rate_tMinus1', 'rate_tMinus2'))
我想使用名称索引而不是列顺序在汇率之后(价格之前)插入这些滞后。
tibble 包 (Adding a column between two columns in a data.frame) 中的 add_column
函数不起作用,因为它只接受原子向量(因此,如果我有 10 个滞后,我将不得不调用 add_column 10次)。我可以在 rate_Lags
矩阵中使用 apply
。但是,然后,我从 rate_Lags
矩阵中丢失了 dimnames。
如果我知道特定列名的位置(任何检索列名位置的函数?),使用数字索引(子集)(https://stat.ethz.ch/pipermail/r-help/2011-August/285534.html)可能会起作用。
有没有简单的方法可以在数据 frame/tibble 对象的特定位置插入一堆列s?
您可能忽略了以下内容
library(dplyr)
I <- which(names(df) == "rate")
if (I == ncol(df)) {
cbind(df, rate_Lags)
} else {
cbind(select(df, 1:I), rate_Lags, select(df, (I+1):ncol(df)))
}
# date rate rate_tMinus1 rate_tMinus2 price
# 1 0.0005 7.50 NA NA 92
# 2 0.0010 6.50 7.50 NA 94
# 3 0.0015 5.54 5.54 7.5 96
也许这不是很优雅,但你只调用一次函数,我相信它或多或少是通用的。
fun <- function(DF, M){
nms_DF <- colnames(DF)
nms_M <- colnames(M)
inx <- which(sapply(nms_DF, function(x) length(grep(x, nms_M)) > 0))
cbind(DF[seq_len(inx)], M, DF[ seq_along(nms_DF)[-seq_len(inx)] ])
}
fun(df, rate_Lags)
# date rate rate_tMinus1 rate_tMinus2 price
#1 01/01/2000 7.50 NA NA 92
#2 02/01/2000 6.50 7.50 NA 94
#3 03/01/2000 5.54 5.54 7.5 96
我们可以 unclass
将数据集 list
然后使用 append
在特定位置插入 'rate_Lags',将 list
重新转换为 data.frame
i1 <- match('rate', names(df))
data.frame(append(unclass(df), as.data.frame(rate_Lags), after = i1))
# date rate rate_tMinus1 rate_tMinus2 price
#1 01/01/2000 7.50 NA NA 92
#2 02/01/2000 6.50 7.50 NA 94
#3 03/01/2000 5.54 5.54 7.5 96
或 tidyverse
library(tidyverse)
rate_Lags %>%
as_tibble %>%
append(unclass(df), ., after = i1) %>%
bind_cols
# A tibble: 3 x 5
# date rate rate_tMinus1 rate_tMinus2 price
# <chr> <dbl> <dbl> <dbl> <dbl>
#1 01/01/2000 7.5 NA NA 92
#2 02/01/2000 6.5 7.5 NA 94
#3 03/01/2000 5.54 5.54 7.5 96
我有一个包含 3 列的 data.frame:日期、费率、价格。我想在费率之后和价格之前添加来自矩阵的列。
df = tibble('date' = c('01/01/2000', '02/01/2000', '03/01/2000'),
'rate' = c(7.50, 6.50, 5.54),
'price' = c(92, 94, 96))
我使用输出矩阵的函数计算了速率的滞后:
rate_Lags = matrix(data = c(NA, 7.50, 5.54, NA, NA, 7.50), ncol=2, dimnames=list(c(), c('rate_tMinus1', 'rate_tMinus2'))
我想使用名称索引而不是列顺序在汇率之后(价格之前)插入这些滞后。
tibble 包 (Adding a column between two columns in a data.frame) 中的 add_column
函数不起作用,因为它只接受原子向量(因此,如果我有 10 个滞后,我将不得不调用 add_column 10次)。我可以在 rate_Lags
矩阵中使用 apply
。但是,然后,我从 rate_Lags
矩阵中丢失了 dimnames。
如果我知道特定列名的位置(任何检索列名位置的函数?),使用数字索引(子集)(https://stat.ethz.ch/pipermail/r-help/2011-August/285534.html)可能会起作用。
有没有简单的方法可以在数据 frame/tibble 对象的特定位置插入一堆列s?
您可能忽略了以下内容
library(dplyr)
I <- which(names(df) == "rate")
if (I == ncol(df)) {
cbind(df, rate_Lags)
} else {
cbind(select(df, 1:I), rate_Lags, select(df, (I+1):ncol(df)))
}
# date rate rate_tMinus1 rate_tMinus2 price
# 1 0.0005 7.50 NA NA 92
# 2 0.0010 6.50 7.50 NA 94
# 3 0.0015 5.54 5.54 7.5 96
也许这不是很优雅,但你只调用一次函数,我相信它或多或少是通用的。
fun <- function(DF, M){
nms_DF <- colnames(DF)
nms_M <- colnames(M)
inx <- which(sapply(nms_DF, function(x) length(grep(x, nms_M)) > 0))
cbind(DF[seq_len(inx)], M, DF[ seq_along(nms_DF)[-seq_len(inx)] ])
}
fun(df, rate_Lags)
# date rate rate_tMinus1 rate_tMinus2 price
#1 01/01/2000 7.50 NA NA 92
#2 02/01/2000 6.50 7.50 NA 94
#3 03/01/2000 5.54 5.54 7.5 96
我们可以 unclass
将数据集 list
然后使用 append
在特定位置插入 'rate_Lags',将 list
重新转换为 data.frame
i1 <- match('rate', names(df))
data.frame(append(unclass(df), as.data.frame(rate_Lags), after = i1))
# date rate rate_tMinus1 rate_tMinus2 price
#1 01/01/2000 7.50 NA NA 92
#2 02/01/2000 6.50 7.50 NA 94
#3 03/01/2000 5.54 5.54 7.5 96
或 tidyverse
library(tidyverse)
rate_Lags %>%
as_tibble %>%
append(unclass(df), ., after = i1) %>%
bind_cols
# A tibble: 3 x 5
# date rate rate_tMinus1 rate_tMinus2 price
# <chr> <dbl> <dbl> <dbl> <dbl>
#1 01/01/2000 7.5 NA NA 92
#2 02/01/2000 6.5 7.5 NA 94
#3 03/01/2000 5.54 5.54 7.5 96