【问题标题】:Conditionally replace values in a data frame with values from another data frame有条件地将数据框中的值替换为另一个数据框中的值
【发布时间】:2020-07-15 00:04:42
【问题描述】:

我有一个从 excel 工作表导入的主工作表,它定义了我的分析应该进行的聚合级别。它定义了药物是否应该汇总到药物名称或分离出来以包括剂型和强度。

这是我使用的主表的示例

df1 <- data.frame(Drug = c("Drug A","Drug B","Drug B","Drug B","Drug C","Drug C","Drug C"),
              Strength = c("All","All","All","All","All","All","All"),
              Dosage_Form = c("All","CAP","SOLN","INJ","CAP","INJ","SOLN"), stringsAsFactors = FALSE)

Drug    Strength   Dosage Form
Drug A  All        All
Drug B  All        CAPS
Drug B  All        SOLN
Drug B  All        INJ
Drug C  All        CAP
Drug C  All        INJ
Drug C  All        SOLN

这告诉我,药物 A 的销售不应细分为包括各种强度,而相反,药物 B 和 C 应该针对这两种剂型有不同的产品线。

我的销售数据来自数据仓库,数据是在药物、强度和剂型级别提取的,此数据的示例如下:

    df2 <- data.frame(Drug = c("Drug A","Drug A","Drug A","Drug B","Drug B","Drug B","Drug C","Drug C","Drug C"),
              STRENGTH = c("80 MCG","80 MCG","80 MCG","80 MCG","80 MCG","80 MCG","80 MCG","80 MCG","80 MCG"),
              DOSAGE_FORM = c("SOLN","CAP","INJ","CAP","INJ","SOLN","CAP","INJ","SOLN"),
              UNITS_SOLD = c(60,100,300,50,20,10,40,20,80), stringsAsFactors = FALSE)

数据如下:

Drug   Strength Dosage_Form Units
Drug A  80 MCG  SOLN         60
Drug A  80 MCG  CAP         100
Drug A  80 MCG  INJ         300
Drug B  80 MCG  CAP          50
Drug B  80 MCG  INJ          20
Drug B  80 MCG  SOLN         10
Drug C  80 MCG  CAP          40
Drug C  80 MCG  INJ          20
Drug C  80 MCG  SOLN         80

我正在寻找一种可以实现以下伪代码的方法:

对于df1 中的每种药物,将df2 中的强度和剂型替换为df1 中的相应值

我的最终结果应该如下所示:

Drug   Strength Dosage_Form Units
Drug A  All     All          60
Drug A  All     All         100
Drug A  All     All         300
Drug B  All     CAP          50
Drug B  All     INJ          20
Drug B  All     SOLN         10
Drug C  All     CAP          40
Drug C  All     INJ          20
Drug C  All     SOLN         80

一旦我将规格和剂型与主表对齐,我就可以使用 group by 和 summarise 将数据聚合到正确的水平

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以加入并进行替换

    library(data.table)
    setDT(df2)[, STRENGTH := "All"]
    df2[setDT(df1)[Strength == Dosage_Form], 
              DOSAGE_FORM :=  Dosage_Form, on = .(Drug)]
    
    df2
    #      Drug STRENGTH DOSAGE_FORM UNITS_SOLD
    #1: Drug A      All         All         60
    #2: Drug A      All         All        100
    #3: Drug A      All         All        300
    #4: Drug B      All         CAP         50
    #5: Drug B      All         INJ         20
    #6: Drug B      All        SOLN         10
    #7: Drug C      All         CAP         40
    #8: Drug C      All         INJ         20
    #9: Drug C      All        SOLN         80
    

    或使用base R

    df1s <- subset(df1, Strength == Dosage_Form)
    i1 <- df2$Drug %in%df1s$Drug
    df2$STRENGTH <- "All"
    df2$DOSAGE_FORM[i1] <- df1s$Dosage_Form
      
    

    【讨论】:

    • – 仅供参考,虽然您的第一个答案是 data.table 解决方案,但第一行“library(dplyr)”暗示它是一个 dplyr 解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    相关资源
    最近更新 更多