【问题标题】:Remove negative values from a dataframe and a positive value that has the same amount从数据框中删除负值和具有相同数量的正值
【发布时间】:2022-12-06 01:54:15
【问题描述】:

我在处理工作中的数据集时遇到问题。该数据集包含在我们网站上进行的交易列表。但是,当客户退回产品时,它会在数据集中添加包含负值的另一行。数据的外观示例:

Person 1        $150        
Person 1       -$150
Person 1        $150
Person 2        $100
Person 2       -$100
Person 3        $50
Person 3        $20

为了使用此数据进行分析,我希望从具有相同数量的同一个人中删除负值和一个值。新数据框的期望输出是:

Person 1      $150
Person 3      $50
Person 3      $20

有关如何解决此问题的任何提示?

【问题讨论】:

  • 我原以为交易 ID/产品 ID/交易日期(以及其他)比简单的客户 ID 和金额更可靠地识别购买/退款对......

标签: r dataframe


【解决方案1】:

如果客户在返回之前没有再次购买,则可能存在黑客攻击:

library(dplyr)
library(stringr)

df |>
  group_by(person) |> 
  mutate(transaction = if_else(str_detect(amount, "-"), row_number()-1, row_number())) |>
  group_by(person, transaction) |> 
  filter(n() == 1) |>
  ungroup()

输出:

# A tibble: 3 × 3
  person  amount transaction
  <chr>   <chr>        <dbl>
1 Person1 $150             3
2 Person3 $50              1
3 Person3 $20              2

【讨论】:

    【解决方案2】:

    正如 cmets 中提到的那样,识别交易的方式似乎非常不可靠。如果您别无选择,则必须按如下方式标记已退款的交易:

    data <- data.frame(person=c(1,1,1,2,2,3,3),  tx=c(150,-150,150,100,-100,50,20))
    
    s <- lapply(split(data, interaction(data$person, abs(data$tx))),(x){
                      cnt <- with(x, min(length(tx[tx<0]), length(tx[tx>0])));
                      within(x, refund <- cumsum(tx<0) <= cnt & cumsum(tx>0) <= cnt ) }) 
                      
                      
    unsplit(s, interaction(data$person, abs(data$tx)))
    #>   person   tx refund
    #> 1      1  150   TRUE
    #> 2      1 -150   TRUE
    #> 3      1  150  FALSE
    #> 4      2  100   TRUE
    #> 5      2 -100   TRUE
    #> 6      3   50  FALSE
    #> 7      3   20  FALSE
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 2023-02-10
      • 2018-08-18
      相关资源
      最近更新 更多