提取列名以创建新列名

Extract a column's name to create a new column name

我有以下简化的数据框。

df <- data.frame("Task1_AI1" = 1:5, "Task1_AI2" = 6:10, "Task2_AI1" = 1:5, "Task2_AI2"= 6:10)
df

看起来像这样:

Task1_AI1 Task1_AI2 Task2_AI1 Task2_AI2
1 6 1 6
2 7 2 7
3 8 3 8
4 9 4 9
5 10 5 10

我想编写一个函数来执行以下操作:

  1. 对每个任务对的值求和,使得Task1_AI1 + Task1_AI2 和Task2 _AI1 + 任务2_AI2
  2. 将每对的总和保存在新列中
  3. 新列的名称将包含相应向量的前 5 个字母。名称应为“Task1”加“_sum”或“Task2”加“_sum”。

新数据框如下所示:

Task1_AI1 Task1_AI2 Task2_AI1 Task2_AI2 Task1_sum Task2_sum
1 6 1 6 7 7
2 7 2 7 9 9
3 8 3 8 11 11
4 9 4 9 13 13
5 10 5 10 15 15

下面的功能是我所拥有的,它实现了我的目标。我想知道如何改进功能。

third_function <- function (df, x, y) {
  df[[paste(str_sub(colnames(df[x]), 1, 5), "_sum", sep='')]] <- df[[x]] + df[[y]]
  df
}

df <- third_function(df, "Task1_AI1", "Task1_AI2")

非常感谢您的指导!

这不是函数,但应该会得到您想要的结果。

library(tidyverse)

df2 <- df %>%
  mutate(Task1_sum= Task1_AI1 + Task1_AI2,
         Task2_sum= Task2_AI1 + Task1_AI2)

在data.table的帮助下:

library(data.table) # load package

sumEquals = function(df){
    a = copy(df)  # copy because data.table works on the object!
    
    # Get the unique names of tasks (I assume there could be more than 2!)
    uniqueNames = unique(substr(names(a), start = 1, stop = 5))
    
    # for each of those unique names do: 
    for (i in uniqueNames){

        # sum row-wise the columns with alike names and assign that to a
        # new column that has the same prefix and the suffix is "_sum"
        a[, paste0(i, "_sum") := apply(.SD, 1, sum), .SDcols = grep(i, names(a), value = TRUE)]
    }

    # return the modified data.frame / data.table
    return(a)
}

检查函数是否有效:

library(data.table)
setDT(df) # convert to a data.table

b = sumEquals(df)

b
   Task1_AI1 Task1_AI2 Task2_AI1 Task2_AI2 Task1_sum Task2_sum
1:         1         6         1         6         7         7
2:         2         7         2         7         9         9
3:         3         8         3         8        11        11
4:         4         9         4         9        13        13
5:         5        10         5        10        15        15