簡體   English   中英

用幾個條件改變一個變量

[英]Mutate a variable with a few conditions

我有一個數據集,想創建一個名為stock的列。 特別是,規則如下。

  1. 如果經紀人在上個月贏得了比賽,他們有一個基於上個月數量的stock
  2. stock在三個月后消失(例如,如果經紀人在2020-02-01 ,則該股票在他們參加2020-06-01的比賽時消失。
  3. 有很多代理AB等。

如何使用tibble創建這樣的行?

date       id    win   quantity stock
<date>     <chr> <dbl> <dbl>   <dbl>
2020-01-01 A     0     60       0
2020-02-01 A     1     50       0
2020-03-01 A     0     50       50 ## have 50 for 3 months because A win in the previous month
2020-04-01 A     1     100      50 
2020-05-01 A     0     10      150 ## have 100 for 3 months because A win in the previous month
2020-06-01 A     0     10      100 ## disappear 50 after 3 months
2020-07-01 A     0     100     100 ## disappear 50 after 3 months
2020-08-01 A     0     100      0  ## disappear 100 after 3 months
2020-01-01 B     0     60       0
2020-02-01 B     0     50       0
2020-03-01 B     0     50       0  
2020-04-01 B     1     10       0 
2020-05-01 B     0     10       10 
2020-08-01 B     0     100      0

編輯:原始數據

date = c("2020-01-01", "2020-02-01", "2020-03-01","2020-04-01", "2020-05-01", "2020-06-01", "2020-07-01", "2020-08-01", "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", "2020-08-01")
id = c("A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B")
win = c(0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
quantity = c(60, 50, 50, 100, 10, 10, 100, 100, 60, 50, 50, 10, 10, 100)
tibble(date = as.Date(date), id = id, win = win, quantity = quantity)

這可以作為對前 3 行的滾動計算來完成(這意味着滾動寬度為 4,我們將忽略當前行)。

(僅供參考,我認為你最后的stock價值應該是 10。)

dplyr

library(dplyr)
# library(zoo) # rollapplyr
dat %>%
  group_by(id) %>%
  mutate(
    stock = zoo::rollapplyr(
      quantity * (win > 0), 4, FUN = function(z) sum(z[-length(z)]),
      by.column = FALSE, partial = TRUE)
  ) %>%
  ungroup()
# # A tibble: 14 x 5
#    date       id      win quantity stock
#    <date>     <chr> <dbl>    <dbl> <dbl>
#  1 2020-01-01 A         0       60     0
#  2 2020-02-01 A         1       50     0
#  3 2020-03-01 A         0       50    50
#  4 2020-04-01 A         1      100    50
#  5 2020-05-01 A         0       10   150
#  6 2020-06-01 A         0       10   100
#  7 2020-07-01 A         0      100   100
#  8 2020-08-01 A         0      100     0
#  9 2020-01-01 B         0       60     0
# 10 2020-02-01 B         0       50     0
# 11 2020-03-01 B         0       50     0
# 12 2020-04-01 B         1       10     0
# 13 2020-05-01 B         0       10    10
# 14 2020-08-01 B         0      100    10

底座 R

(但仍在使用zoo::rollapplyr 。)

dat$stock <- 
  ave(dat$quantity * (dat$win > 0), dat$id, FUN = function(z) {
    zoo::rollapplyr(z, 4, FUN = function(z) sum(z[-length(z)]),
                    by.column = FALSE, partial = TRUE)
  })

data.table

library(data.table)
DT <- as.data.table(dat)
DT[, stock := zoo::rollapplyr(quantity * (win > 0), 4, FUN = function(z) sum(z[-length(z)]),
                             by.column = FALSE, partial = TRUE),
   by = .(id) ]

(我在這里使用DT <- as.data.table(dat)以防用戶選擇使用它而沒有意識到setDT(dat)對數據所做的就地更改。我相信setDT(dat)是從另一個框架轉換為data.table類的規范和推薦方法,如果您要從"tbl_df"進行切換,請使用它。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM