Найдите определенные значения c и используйте их для создания новой переменной. - PullRequest
1 голос
/ 03 марта 2020

Я наблюдаю за тем, как человек все больше и больше экономит деньги. Как только он купит что-то на эти деньги, я смогу понять, сколько он потратил на эту покупку. Теперь я хочу создать новую переменную, показывающую, насколько далеко / близко / выше он находился в данный момент времени от совершения этой покупки. Я наблюдаю несколько покупок для некоторых людей, но для других нет покупок (... в этом случае я хочу использовать среднее значение всех расходов других людей, чтобы указать расстояние до цели покупки.

Пример набора данных:

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  

1 Ответ

2 голосов
/ 03 марта 2020
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    

В ваших данных образца все идентификаторы заканчиваются покупкой. Если это не так в ваших реальных данных, вы можете использовать последнюю покупку этого идентификатора в качестве цели для следующей (ненаблюдаемой) покупки, а не в качестве глобального среднего значения. Для этого измените направление fill на "updown".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...