通过列名中的ID处理数据框列

时间:2018-08-14 23:57:47

标签: r dataframe

我有一个看起来像这样的数据集:

DT <- data.frame( rnorm(5),
              rnorm(5),
              rnorm(5),
              rnorm(5),
              rnorm(5),
              rnorm(5))
names(DT) = c('a1[1]','a1[2]','a1[3]','a2[1]','a2[2]','a2[3]')
str(DT)

我想创建新的列,例如:

diffa1 = a1[1] - a2[1] 
diffa2 = a1[2] - a2[2]
diffa3 = a1[3] - a2[3]

我想知道是否有必要这样做,而不必手动更改括号中的ID,因为我有a1[1]a1[100]a2[1]到{{1 }}等。谢谢!

2 个答案:

答案 0 :(得分:1)

我们可以使用lapply在列名中循环显示数字。

diffa <- as.data.frame(lapply(1:3, function(x){
  DT[paste0("a1[", x, "]")] - DT[paste0("a2[", x, "]")] 
}))
diffa
#        a1.1.      a1.2.       a1.3.
# 1  0.9160836 -0.3508354  0.04981186
# 2  0.7397111  1.9147110 -1.47307780
# 3  0.6889159 -0.7672135 -4.24234927
# 4 -0.2701030 -1.3199004  2.55248732
# 5  1.2267170 -2.0815192 -1.97941609

或使用grepl选择要创建两个数据帧的列,然后进行操作。

DT1 <- DT[grep("^a1", names(DT))]
DT2 <- DT[grep("^a2", names(DT))]
diffa <- DT1 - DT2
diffa
#        a1[1]      a1[2]       a1[3]
# 1  0.9160836 -0.3508354  0.04981186
# 2  0.7397111  1.9147110 -1.47307780
# 3  0.6889159 -0.7672135 -4.24234927
# 4 -0.2701030 -1.3199004  2.55248732
# 5  1.2267170 -2.0815192 -1.97941609

数据

set.seed(158)

DT <- data.frame( rnorm(5),
                  rnorm(5),
                  rnorm(5),
                  rnorm(5),
                  rnorm(5),
                  rnorm(5))
names(DT) = c('a1[1]','a1[2]','a1[3]','a2[1]','a2[2]','a2[3]')

答案 1 :(得分:1)

这是map2的另一种选择,用于减去相应的列

library(tidyverse)
map2_df(DT %>% 
          select(matches("a1")),
        DT %>% 
          select(matches("a2")), `-`)