【问题标题】:Search for specific values and use them to construct a new variable搜索特定值并使用它们构造一个新变量
【发布时间】:2020-03-03 12:42:31
【问题描述】:

我观察到一个人随着时间的推移节省了越来越多的钱。一旦他用这笔钱买了东西,我就可以观察他为这次购买花了多少钱。现在我想创建一个新变量,指示他在给定时间点距离进行购买有多远/近/高。我观察到一些人多次购买,但另一些人没有购买(......在这种情况下,我想使用其他人所有支出的平均值来表示距离购买目标的距离。

示例数据集:

da1 <- data.frame(person_id = c(1,1,1,1,2,2,2,2,3,3,3,3), week=c(1,2,3,4,1,2,3,4,1,2,3,4), money = c(100,120,160,80,20,40,60,80,10,6,30,20))

da1
   person_id week money
1          1    1   100
2          1    2   120
3          1    3   160
4          1    4    80
5          2    1    20
6          2    2    40
7          2    3    60
8          2    4    80
9          3    1    10
10         3    2     6
11         3    3    30
12         3    4    20

这是预期的输出。 purchase_distance 显示了我需要进行的计算。

da2 <- data.frame(person_id = c(1,1,1,1,2,2,2,2,3,3,3,3), week=c(1,2,3,4,1,2,3,4,1,2,3,4), money = c(100,120,160,80,20,40,60,80,10,6,30,20), purchase_distance = c(100/80, 120/80,160/80,80/80,20/mean(c(80,10,4)), 40/31,60/31,80/31,10/4,6/4,30/10,20/10))

da2
   person_id week money purchase_distance
1          1    1   100              1.25
2          1    2   120              1.50
3          1    3   160              2.00
4          1    4    80              1.00
5          2    1    20              0.64
6          2    2    40              1.29
7          2    3    60              1.94
8          2    4    80              2.58
9          3    1    10              2.50
10         3    2     6              1.50
11         3    3    30              3.00
12         3    4    20              2.00

这是我尝试过的,但它不起作用,而且这种编码方式,它无法识别每个人的多次购买......

da3 = group_by(da1, person_id) %>%
    mutate(change_in_money = money-lag(money)) %>%
    group_by(person_id, week) %>%
    mutate(purchase_distance = money/abs(max(change_in_money)))

da3
# A tibble: 12 x 5
# Groups:   person_id, week [12]
   person_id  week money change_in_money purchase_distance
       <dbl> <dbl> <dbl>           <dbl>             <dbl>
 1         1     1   100              NA             NA   
 2         1     2   120              20              6   
 3         1     3   160              40              4   
 4         1     4    80             -80              1   
 5         2     1    20              NA             NA   
 6         2     2    40              20              2   
 7         2     3    60              20              3   
 8         2     4    80              20              4   
 9         3     1    10              NA             NA   
10         3     2     6              -4              1.5 
11         3     3    30              24              1.25
12         3     4    20             -10              2  

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    da1 %>%
      group_by(person_id) %>%
      mutate(
        diff = money-lag(money),
        target = ifelse(diff < 0, diff, NA) 
      ) %>%
      tidyr::fill(target, .direction = "up") %>% 
      ungroup() %>%
      mutate(
        target = coalesce(target, mean(diff[diff < 0], na.rm = TRUE)),
        purchase_distance = money / abs(target)
      )
    # # A tibble: 12 x 6
    #    person_id  week money  diff target purchase_distance
    #        <dbl> <dbl> <dbl> <dbl>  <dbl>             <dbl>
    #  1         1     1   100    NA  -80               1.25 
    #  2         1     2   120    20  -80               1.5  
    #  3         1     3   160    40  -80               2    
    #  4         1     4    80   -80  -80               1    
    #  5         2     1    20    NA  -31.3             0.638
    #  6         2     2    40    20  -31.3             1.28 
    #  7         2     3    60    20  -31.3             1.91 
    #  8         2     4    80    20  -31.3             2.55 
    #  9         3     1    10    NA   -4               2.5  
    # 10         3     2     6    -4   -4               1.5  
    # 11         3     3    30    24  -10               3    
    # 12         3     4    20   -10  -10               2    
    

    在您的示例数据中,所有 ID 都以购买结尾。如果您的真实数据不是这种情况,您可能希望使用该 ID 的最后一次购买作为下一次(未观察到的)购买的目标,而不是全局平均值。为此,请将fill 方向更改为"updown"

    【讨论】:

    • 太棒了,非常感谢!关于更改填充方向的评论实际上对我的数据非常重要,干得好!
    • 尝试使用“updown”方向,R 告诉我“arg”应该是“down”、“up”之一。发生了什么?
    • 也许你有一个旧版本的tidyr?这对我来说可以。尝试更新您的软件包。如果还是有问题,可以通过 2 个fills、tidyr::fill(target, .direction = "up") %&gt;% tidyr::fill(target, .direction = "down") 来解决。
    猜你喜欢
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多