【问题标题】:Apply a function to the columns of a dataframe every two columns, store the results of that function in a list, and then insert that list as a column每两列将函数应用于数据框的列,将该函数的结果存储在列表中,然后将该列表作为列插入
【发布时间】:2021-07-02 10:33:46
【问题描述】:

所以我有一个 6 列的数据框,它们都是数字且长度相同。数据框如下所示:

df <- data.frame(var1 = 1:10, var2 = 5:15, var3 = 7:17, var4 = 3:13, var5 = 20:30, var6 = 15:25)
print(df)

我想要做的是获取 var1 和 var2 并减去它们 (var1 - var2) 并在新列中获取结果,该列将在 var2 之后将自身插入到同一数据帧中。然后我想取 var3 和 var4 并减去它们 (var3 - var4) 并在新列中得到结果,我将在 var4 之后插入,依此类推。

有什么建议吗?

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    mutate中的.after来自dplyr,可以使用

    library(dplyr)
    df %>% 
       mutate(var12 = var1 - var2, .after = var2) %>%
       mutate(var34 = var3 - var4, .after = var4)
    

    -输出

    #    var1 var2 var12 var3 var4 var34 var5 var6
    #1     1    5    -4    7    3     4   20   15
    #2     2    6    -4    8    4     4   21   16
    #3     3    7    -4    9    5     4   22   17
    #4     4    8    -4   10    6     4   23   18
    #5     5    9    -4   11    7     4   24   19
    #6     6   10    -4   12    8     4   25   20
    #7     7   11    -4   13    9     4   26   21
    #8     8   12    -4   14   10     4   27   22
    #9     9   13    -4   15   11     4   28   23
    #10   10   14    -4   16   12     4   29   24
    #11   11   15    -4   17   13     4   30   25
    

    如果我们需要在每 2 列之后创建列

    library(stringr)
    out <- df
    for(i in seq(2, ncol(df), by = 2)) {
         out <- out %>%
                 mutate(!! str_c('var', i-1, i) := 
                   .[[names(df)[i]]] - .[[names(df)[i-1]]],
                  .after = all_of(names(df)[i]))
       } 
            
    

    -输出

    out
    #   var1 var2 var12 var3 var4 var34 var5 var6 var56
    #1     1    5     4    7    3    -4   20   15    -5
    #2     2    6     4    8    4    -4   21   16    -5
    #3     3    7     4    9    5    -4   22   17    -5
    #4     4    8     4   10    6    -4   23   18    -5
    #5     5    9     4   11    7    -4   24   19    -5
    #6     6   10     4   12    8    -4   25   20    -5
    #7     7   11     4   13    9    -4   26   21    -5
    #8     8   12     4   14   10    -4   27   22    -5
    #9     9   13     4   15   11    -4   28   23    -5
    #10   10   14     4   16   12    -4   29   24    -5
    #11   11   15     4   17   13    -4   30   25    -5
     
    

    base R,我们也可以这样做

    out1 <- df[c(FALSE, TRUE)] - df[c(TRUE, FALSE)]
    names(out1) <- paste0(names(out1), "_", names(df)[c(TRUE, FALSE)])
    

    然后我们根据列名cbind 数据集和order

    out2 <- cbind(df, out1)
    out3 <- out2[gtools::mixedorder(names(out2))]
    out3
    # var1 var2 var2_var1 var3 var4 var4_var3 var5 var6 var6_var5
    #1     1    5         4    7    3        -4   20   15        -5
    #2     2    6         4    8    4        -4   21   16        -5
    #3     3    7         4    9    5        -4   22   17        -5
    #4     4    8         4   10    6        -4   23   18        -5
    #5     5    9         4   11    7        -4   24   19        -5
    #6     6   10         4   12    8        -4   25   20        -5
    #7     7   11         4   13    9        -4   26   21        -5
    #8     8   12         4   14   10        -4   27   22        -5
    #9     9   13         4   15   11        -4   28   23        -5
    #10   10   14         4   16   12        -4   29   24        -5
    #11   11   15         4   17   13        -4   30   25        -5
    

    数据

    df <- structure(list(var1 = 1:11, var2 = 5:15, var3 = 7:17, var4 = 3:13, 
        var5 = 20:30, var6 = 15:25), class = "data.frame", row.names = c(NA, 
    -11L))
    

    【讨论】:

    • 是的,这可以工作,但我正在寻找更“自动”的东西,比如外观或其他东西。那是因为我的数据框实际上有 60 列,我希望脚本可以重现到具有不同列名的其他数据框中,所以我不能对新变量一一编码
    • @TomasC8 你知道需要更改的列名以及之后应该保留的位置
    • 逻辑始终相同:var2 将从 var1 中减去,结果将是一个新列,它将在 var2 之后插入自身。然后,var4(现在是第 5 列,因为在第 3 号位置添加了一个新列)将从 var3(现在是第 4 列)中减去,结果将是一个新列将在 var4 之后插入自身,依此类推
    • @TomasC8 根据您的逻辑,这两个更新的解决方案应该可以工作。可能是你有不同的逻辑
    猜你喜欢
    • 1970-01-01
    • 2021-03-20
    • 2017-04-22
    • 2020-04-24
    • 2017-08-20
    • 2020-03-09
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多