จะทราบความแตกต่างระหว่างตัวแปรและความล่าช้าโดยพิจารณาจากวันที่ของเดือนต่อกลุ่มได้อย่างไร

โดยพื้นฐานแล้ว ฉันมีชุดข้อมูลที่มีตัวแปรระบุกลุ่ม วันที่ และค่าของตัวแปร ฉันจำเป็นต้องหาผลต่างระหว่างมูลค่ากับมูลค่าสิ้นปีก่อนหน้าต่อกลุ่ม เนื่องจากข้อมูลมีความสมดุล ฉันจึงพยายามทำเช่นนั้นด้วย dplyr::lag โดยแทรกความล่าช้าตามเดือนของการสังเกต:

x <- x %>% group_by(g) %>% mutate(y = v - lag(v, n=month(d))

อย่างไรก็ตามสิ่งนี้ไม่ได้ผล

ผลลัพธ์ควรเป็น:

ชุดข้อมูลจำลอง:

x <- data.frame('g'=c('B','B','B','C','A','A','A','A','A','A'),'d'=c('2018-11-30', '2018-12-31','2019-01-31','2019-12-31','2016-12-31','2017-11-30','2017-12-31','2018-12-31','2019-01-31','2019-02-28'),'v'=c(300,200,250,100,400,150,200,500,400,500))

ตัวแปรที่ต้องการ:

y <- c(NA,NA,-50,NA,NA,-250,-200,300,-100,0)

ชุดข้อมูลใหม่:

cbind(x,y)

person Ramiro    schedule 04.12.2019    source แหล่งที่มา
comment
ในชุดข้อมูลจำลองของคุณมีเพียง 1 กลุ่ม: A และมี 2 ปี: 2018 และ 2019 ดังนั้น 31-12-2561 จะเป็นปีเดียวที่สิ้นสุดของปีก่อนต่อกลุ่ม ผมถือว่ากลุ่มละไม่ติดต่อกัน 3 ปี (ไม่อย่างนั้นจะมี 2 ปีสุดท้ายของปีต่อกลุ่ม) จากนั้นคุณอาจ 1) แยก year component of the date - 1 เพื่อรับปีก่อนหน้า และ 2) ใช้ max() เพื่อรับสิ้นปี   -  person FannieY    schedule 05.12.2019
comment
ขออภัย ฉันจะทำให้ชุดข้อมูลจำลองมีความครอบคลุมมากขึ้น แท้จริงแล้วนั่นคือสิ่งที่ผมตั้งใจจะทำ อย่างไรก็ตาม ในไพพ์ dplyr เราจะหาค่าของกลุ่มเดียวกันโดยปี = ปี-1 และเดือนสูงสุดได้อย่างไร กล่าวอีกนัยหนึ่ง ให้สร้างตัวแปรซึ่งก็คือ y = x - x[year==year-1 & month=max(month of that year)]?   -  person Ramiro    schedule 05.12.2019
comment
ฉันเกรงว่าจะไม่สามารถรับค่าของตัวแปรที่คุณต้องการได้ (NA, NA, -50, NA, 500, 100, 0) หากอินพุตเป็น data.frame('g'=c('B','B','B','C','A','A','A'),'d'=c(' 30-11-2561', '31-12-2561','2019-01-31','2017-12-31','2018-12-31','2019-01-31','2019- 02-28'),'v'=c(300,200,250,400,500,400,500)) ผลลัพธ์ที่คาดหวังของฉัน y คือ: (NA, NA, 50, NA, NA, -100, 0)   -  person FannieY    schedule 05.12.2019
comment
อันที่จริงความผิดพลาดของฉัน (ในระยะหลังฉันต้องการให้สิ้นปีไม่ดึง NAs แต่เป็นมูลค่าของตัวเอง แม้ว่าจะสามารถทำได้ง่าย ๆ ด้วยคำสั่ง ifelse)   -  person Ramiro    schedule 05.12.2019


คำตอบ (2)


แนวคิดผ่าน dplyr สามารถค้นหาวันสุดท้าย รับดัชนี และใช้สิ่งนั้นเพื่อลบแล้วแปลงเป็น NA เช่น

library(dplyr)

x %>% 
 group_by(g) %>% 
 mutate(new = which(sub('^[0-9]+-([0-9]+-[0-9]+)$', '\\1', d) == '12-31'), 
        y = v - v[new], 
        y = replace(y, row_number() <= new, NA)) %>% 
 select(-new)

ซึ่งจะช่วยให้,

# A tibble: 7 x 4
# Groups:   g [3]
  g     d              v     y
  <fct> <fct>      <dbl> <dbl>
1 B     2018-11-30   300    NA
2 B     2018-12-31   200    NA
3 B     2019-01-31   250    50
4 C     2017-12-31   400    NA
5 A     2018-12-31   500    NA
6 A     2019-01-31   400  -100
7 A     2019-02-28   500     0
person Sotos    schedule 05.12.2019
comment
มันใช้งานไม่ได้เพราะชุดข้อมูลของฉันมีมากกว่าสองปีต่อกลุ่ม ฉันจะปรับการแยกวิเคราะห์เพื่อให้ค้นหาค่าที่มี year = year-1 และ '12-31' ในแนวทางนี้ได้อย่างไร ฉันไม่คุ้นเคยกับนิพจน์ทั่วไป - person Ramiro; 05.12.2019
comment
นี่เป็นรายละเอียดที่สำคัญที่ต้องละทิ้ง โปรดอัปเดตชุดข้อมูลและผลลัพธ์ที่คาดหวังในคำถามของคุณ - person Sotos; 05.12.2019
comment
แนวทางของคุณคือสิ่งที่ฉันต้องการ แต่ฉันต้องการให้สิ่งใหม่อ้างอิงถึง %y-1+'-12-31' - person Ramiro; 05.12.2019
comment
เพิ่มไว้ในชุดข้อมูล - person Ramiro; 05.12.2019

ในท้ายที่สุด ฉันตัดสินใจสร้างตัวแปรเสริม ('eoy') เพื่อระบุแถวของสิ้นปีที่สอดคล้องกันในแต่ละกลุ่มสำหรับแต่ละแถว ต้องใช้การวนซ้ำและไม่มีประสิทธิภาพ แต่อำนวยความสะดวกในการคำนวณที่เหลือซึ่งจะขึ้นอยู่กับสิ่งนี้ การคำนวณที่ต้องการจะกลายเป็น:

กลายพันธุ์('y'= x - x[eoy])

person Ramiro    schedule 05.12.2019