【问题标题】:Apply a function that uses a column in the dataframe as input to every value on 1:n columns and rows将使用数据框中的列作为输入的函数应用到 1:n 列和行上的每个值
【发布时间】:2018-03-28 01:10:45
【问题描述】:

我正在尝试分两步将两个简单函数应用于矩阵或 df 中 1:n 列上的所有行,其中我想使用最后一列中的值作为函数的输入。 这个问题可能是重复的,但是我根本找不到我正在寻找的解决方案。我曾尝试编写一个函数、apply 和 dplyr 函数,但在如何引用特定列并为 x、y 的每个组合获取单独的结果时遇到问题。

我在这里 [how to apply a function to every row of a matrix (or a data frame) in R 和这里查看了答案:

但是这些操作大多是行或列的,我需要这个函数来处理每个观察,即

这是我的数据的简化示例 - 但我的数据帧在变量和长度方面的长度不同,因为我正在测量可变深度的深度剖面。

第一个想要的功能:

df<- matrix(c( 
      1.11543500, 1.09273900, 1.09362300, 1.09073300, 1.09668300, 0.0876387143,
      1.08729500, 1.06946100, 1.06227900, 1.06633600, 1.06690000, 0.0853604143,
      1.05458300, 1.03921000, 1.03225300, 1.03782000, 1.03416200, 0.0790749429,
      1.02783210, 1.01204520, 1.00525750, 1.00781250, 1.00666170,  0.0756004571
    ), nrow = 4, byrow = TRUE)

首先我需要使用宽格式的 df 来应用类似的函数;

对于 V1:V5 的每一行减去 V6,这将给出这样的输出(最好将 V6 排除在外:

 df1
       V1         V2          V3          V4           V5          V6
1 1.027796286   1.005100286 1.005984286 1.003094286 1.009044286 0.087638714
2 1.001934586   0.984100586 0.976918586 0.980975586 0.981539586 0.085360414
3 0.975508057   0.960135057 0.953178057 0.958745057 0.955087057 0.079074943
4 0.952231643   0.936444743 0.929657043 0.932212043 0.931061243 0.075600457

我试过了:

    df1<- apply(df, 1, function(x) x[1:5]-x[6])

它给了我这个,这是错误的:

df1    [,1]      [,2]      [,3]      [,4]
 [1,] 1.027796 1.0019346 0.9755081 0.9522316
 [2,] 1.005100 0.9841006 0.9601351 0.9364447
 [3,] 1.005984 0.9769186 0.9531781 0.9296570
 [4,] 1.003094 0.9809756 0.9587451 0.9322120
 [5,] 1.009044 0.9815396 0.9550871 0.9310612

有人对如何更正代码有建议吗?我也愿意提供建议,例如 dplyr 或要调用的函数。

我希望它也能给我一个关于如何继续下一步的答案,我必须将第一次计算的结果转置并添加一些具有温度和盐度值以及常数的其他列通过如下公式计算:

  x = z- [constant_t * (t1 - t2) + constant_s * S]

其中 z 将是第一次计算的输出。

【问题讨论】:

    标签: r dplyr apply


    【解决方案1】:

    您可以使用dplyr 中的mutate_at 来执行此操作。我使用ncol 来确定要使用的列。然后,您可以按照@PoGibas 的建议使用t() 继续下一步。

    library(dplyr)
    df <- as_tibble(df) 
    df1 <- mutate_at(df, 1:(ncol(df) -1), funs(. - df[[ncol(df)]]))
    df1
    #> # A tibble: 4 x 6
    #>          V1        V2        V3        V4        V5         V6
    #>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>      <dbl>
    #> 1 1.0277963 1.0051003 1.0059843 1.0030943 1.0090443 0.08763871
    #> 2 1.0019346 0.9841006 0.9769186 0.9809756 0.9815396 0.08536041
    #> 3 0.9755081 0.9601351 0.9531781 0.9587451 0.9550871 0.07907494
    #> 4 0.9522316 0.9364447 0.9296570 0.9322120 0.9310612 0.07560046
    
    t(df1)
    #>          [,1]       [,2]       [,3]       [,4]
    #> V1 1.02779629 1.00193459 0.97550806 0.95223164
    #> V2 1.00510029 0.98410059 0.96013506 0.93644474
    #> V3 1.00598429 0.97691859 0.95317806 0.92965704
    #> V4 1.00309429 0.98097559 0.95874506 0.93221204
    #> V5 1.00904429 0.98153959 0.95508706 0.93106124
    #> V6 0.08763871 0.08536041 0.07907494 0.07560046
    

    如果您希望从结果中删除最后一个变量,您可以使用transmute_at 而不是mutate_at

    transmute_at(df, 1:(ncol(df) -1), funs(. - df[[ncol(df)]]))
    
    #> # A tibble: 4 x 5
    #>          V1        V2        V3        V4        V5
    #>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
    #> 1 1.0277963 1.0051003 1.0059843 1.0030943 1.0090443
    #> 2 1.0019346 0.9841006 0.9769186 0.9809756 0.9815396
    #> 3 0.9755081 0.9601351 0.9531781 0.9587451 0.9550871
    #> 4 0.9522316 0.9364447 0.9296570 0.9322120 0.9310612
    

    【讨论】:

    • 谢谢@markdly!它工作正常!我总是忘记“。”在玩乐中!但只有这样才能像你的整个代码那样有帮助。但是,正如我问@PoGibas - 你的脚本中是否有一种方法可以引用 col 名称?下一步涉及5列,它会更容易,更安全!按名称调用它们,因为我的 df 有 178 个变量。
    • 而 tibble 对我来说是新的!好东西!/谢谢
    • @E.ThereseHarvey,很高兴它有帮助!要在上面的示例中使用列名,您可以使用mutate_at(df, vars(V1:V5), funs(. - V6))。您可能还想查看?dplyr::select_helpers,了解其他可以根据变量名称而不是vars() 中的V1:V5 来选择变量的方法。
    • 谢谢,是的,当然有“。”在它工作的乐趣!我会调查 select_helpers。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    相关资源
    最近更新 更多