【问题标题】:How to multiply to separate dataframes and apply a function to get a new dataframe with the result in R如何乘以分离数据帧并应用函数以在 R 中获得结果的新数据帧
【发布时间】:2020-06-18 23:27:45
【问题描述】:

我有两个数据框。其中一个具有不同 ID 的代码(1 或 -1)。

data.1 <- read.csv(text = "
IDs qt1 qt2 qt3
pl1 -1 -1 -1
pl2 1 -1 1
pl3 1 1 1
pl4 -1 -1 -1
pl5 1 1 1
pl6 1 1 1
pl7 1 -1 1
pl8 1 1 1 
pl9 -1 -1 -1
pl0 -1 -1 -1
")

还有另一个数据框,包含三个变量、参数和估计值。

Data.2 <- read.csv(text = "
variable parameter estimate
varA a0 2.3
varA a1 0.859
varA a2 0.527
varA a3 0.774
VarB b0 19.08
VarB b1 0.412
VarB b2 0.022
VarB b3 0.448
VarC c0 5.4
VarC c1 0.492
VarC c2 0.094
VarC c3 0.971
")

对于每个 ID,我需要估计每个变量的值。例如,对于pl1和VarA,我需要计算的值是a0 + (a1*qt1) + (a2*qt2) + (a3*qt3)。

每个 ID 的预期结果是这样的:

当然,这是一个模拟示例,我有数百个 ID 和变量。因此,我需要一些自动的方法来做到这一点。我正在探索 dplyr::rowwise 的选项并尝试编写一个函数,但找不到编写合理代码的方法。

任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: r function dataframe rowwise


    【解决方案1】:

    您可以按行拆分 qt 值并插入 1 作为第一个值,按变量拆分估计值,然后相乘和求和:

    qt_vals <- split(cbind(qt0 = 1, data.1[-1]), f = data.1$IDs)
    vals <- split(Data.2$estimate, f = Data.2$variable)
    
    sapply(vals, function(x) sapply(qt_vals, function(y) sum(x * y)))
    
         varA   VarB  VarC
    pl0 0.140 18.198 3.843
    pl1 0.140 18.198 3.843
    pl2 3.406 19.918 6.769
    pl3 4.460 19.962 6.957
    pl4 0.140 18.198 3.843
    pl5 4.460 19.962 6.957
    pl6 4.460 19.962 6.957
    pl7 3.406 19.918 6.769
    pl8 4.460 19.962 6.957
    pl9 0.140 18.198 3.843
    

    请注意,图像中有pl10,但示例数据中有pl0,这是图像与上述结果之间差异的根源。

    【讨论】:

    • 非常感谢您的帮助。它工作完美。超级高效。
    【解决方案2】:

    在稍微重塑为宽格式后,考虑在数据帧之间进行交叉连接合并。然后,在没有任何循环的情况下运行您指定的计算。

    # ADD COLUMN + RESHAPE WIDE
    wide_data.2 <- reshape(transform(data.2, var_letter=gsub("[a-z]", "", parameter)), 
                           idvar = "variable", v.names = "estimate",  drop = "parameter",
                           timevar = "var_letter", direction = "wide")
    
    # CROSS JOIN MERGE + CALCULATION
    merge_data <- within(merge(wide_data.2, data.1, by=NULL), {
            calc_value <- estimate.0 + (estimate.1*qt1) + (estimate.2*qt2) + (estimate.3*qt3)
    })
    
    # RESHAPE WIDE
    wide_merge_data <- reshape(merge_data[c("IDs", "calc_value", "variable")], 
                               idvar = "IDs", v.names = "calc_value", 
                               timevar = "variable", new.row.names = 1:nrow(data.1),
                               direction = "wide")
    wide_merge_data 
    
    #    IDs calc_value.VarA calc_value.VarB calc_value.VarC
    # 1  pl1           0.140          18.198           3.843
    # 2  pl2           3.406          19.918           6.769
    # 3  pl3           4.460          19.962           6.957
    # 4  pl4           0.140          18.198           3.843
    # 5  pl5           4.460          19.962           6.957
    # 6  pl6           4.460          19.962           6.957
    # 7  pl7           3.406          19.918           6.769
    # 8  pl8           4.460          19.962           6.957
    # 9  pl9           0.140          18.198           3.843
    # 10 pl0           0.140          18.198           3.843
    

    【讨论】:

    • 非常感谢@Parfait。也很好的解决方案。我更喜欢另一个,因为它对我的编码更少。
    • 明白。虽然冗长,但这个解决方案是三行,没有单个或嵌套循环(for 或 apply)。最后reshape 是您请求的格式。理想情况下,您希望将所有内容保存为 tidy 或长格式。此外,该解决方案清楚地显示了代码可读性和可维护性的原始公式,以及易于更改的算术。编码愉快!
    • 是的,我真的很喜欢原始公式的可读性。我将将此解决方案用于我的其他任务。非常感谢您的时间和知识!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2014-03-05
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多