在数据框中的特定位置添加列的优雅方式

时间:2018-06-19 03:19:09

标签: r dataframe apply matrix-indexing tibble

我有一个带有3个cols的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次)。我可以在apply矩阵中使用rate_Lags。然而,然而,我失去了rate_Lags矩阵的dimnames。

如果我知道特定列名的位置(任何检索列名位置的函数?),那么使用数字索引(子集)(https://stat.ethz.ch/pipermail/r-help/2011-August/285534.html)可能有效。

是否有任何简单的方法可以将一串列 s 插入数据框/ tibble对象的特定位置?

3 个答案:

答案 0 :(得分:4)

您可能会忽略以下

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

答案 1 :(得分:1)

也许这不是很优雅,但你只需要调用一次这个功能,我相信它或多或少都是通用的。

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

答案 2 :(得分:1)

我们可以unclass数据集为list,然后使用append在特定位置插入'rate_Lags',将list重新转换为data.frame < / p>

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