การใส่ NA ด้วย LOCF แบบมีเงื่อนไข

ฉันได้อัปเดตปัญหาใหม่ที่แตกต่าง คราวนี้ฉันต้องการรับคอลัมน์ Oxy2 จาก Oxy

ID Oxy  Y   Oxy2
1  NA 2010   NA
1   0 2011    0
1  NA 2012   NA
1   1 2013    1
1  NA 2014    1
1  NA 2015    1
1  -1 2016    1
2   0 2011    0
2  NA 2012   NA
2   1 2013    1
2  -1 2014    1
3   0 2012    0
3  -1 2013   -1
3  NA 2014   NA
4  -1 2010   -1
4   1 2011    1
4  -1 2012    1
4  -1 2013    1
4   0 2014    1
4  NA 2015    1

โดยพื้นฐานแล้ว ฉันจำเป็นต้องเก็บ NA ไว้ (ถ้ามี) เมื่อค่าก่อนหน้าของตัวแปร Oxy ของฉันคือ 0 หรือ -1 และแทนที่ทุกสิ่งที่มาหลังจาก 1 ตัวแรกปรากฏขึ้นด้วย 1

ขอขอบคุณอีกครั้งสำหรับข้อเสนอแนะของคุณ


person SimoneG    schedule 06.12.2019    source แหล่งที่มา


คำตอบ (2)


library(dplyr)
library(zoo)
df %>% 
   group_by(ID) %>% 
   mutate(Ins1=na.locf(ifelse(is.na(Ins) & lag(Ins)==0, 999, Ins), na.rm = FALSE), Ins2=na_if(Ins1, 999))
   #one step version
   #mutate(Ins1 = na_if(na.locf(ifelse(is.na(Ins) & lag(Ins)==0, 999, Ins), na.rm = FALSE), 999))

# A tibble: 8 x 5
# Groups:   ID [2]
     ID   Ins     Y  Ins1  Ins2
  <int> <int> <int> <dbl> <dbl>
1     1     0  2010     0     0
2     1    NA  2011   999    NA
3     1     1  2012     1     1
4     1    NA  2013     1     1
5     1    NA  2014     1     1
6     2     0  2011     0     0
7     2     0  2012     0     0
8     2    NA  2013   999    NA

อัปเดต: เพื่อแก้ไขปัญหา -1 ฉันเพิ่มการเปลี่ยนแปลงเล็กน้อยกับสิ่งที่ @ user12492692 แนะนำในการแก้ไข กล่าวคือแทนที่ | ด้วย %in%

df %>% 
  group_by(ID) %>% 
  mutate(Ins1 = na.locf(ifelse(is.na(Ins) & lag(Ins) %in% c(0,-1), 999, Ins), na.rm = FALSE), 
         Ins2 = na_if(Ins1, 999))
person A. Suliman    schedule 06.12.2019
comment
ขอบคุณมาก @A.Suliman สำหรับการตอบกลับของคุณ จริงๆ แล้วอาจมี ID บางตัวที่อาจมี INS หายไปตั้งแต่เริ่มต้น มันทำให้ฉันมีข้อผิดพลาดต่อไปนี้คอลัมน์ Ins1 ต้องมีความยาว 10 (ขนาดกลุ่ม) หรือหนึ่งอันไม่ใช่ 9 - person SimoneG; 06.12.2019
comment
@ user:8467042 คุณช่วยฉันอีกครั้งได้ไหม? - person SimoneG; 10.12.2019
comment
@ user12492692 ฉันคิดว่าเป็นการดีกว่าที่จะถามคำถามใหม่ ให้ลิงค์แล้วฉันจะดูมัน - person A. Suliman; 10.12.2019
comment
@ user8467042 stackoverflow.com/questions/59275742/ - person SimoneG; 11.12.2019

นี่เป็นอีกทางเลือกหนึ่งที่เติมค่าทั้งหมดโดยใช้ LOCF แล้วเพิ่ม NA ตามหลังศูนย์:

library(dplyr)

df1 %>%
  mutate(Ins_b = Ins[!is.na(Ins)][cumsum(!is.na(Ins))],
         Ins_b = replace(Ins_b, is.na(Ins) & Ins_b == 0, NA))

  ID Ins    Y Ins_b
1  1   0 2010     0
2  1  NA 2011    NA
3  1   1 2012     1
4  1  NA 2013     1
5  1  NA 2014     1
6  2   0 2011     0
7  2   0 2012     0
8  2  NA 2013    NA
person Andrew    schedule 06.12.2019
comment
ขอบคุณ @Andrew สำหรับทางออกที่ดีของคุณ มันใช้งานได้ แต่ล้มเหลวสำหรับการสังเกตที่มี Ins แรกเป็น NA (ซึ่งควรยังคงเป็น NA) - person SimoneG; 06.12.2019
comment
@ user12492692 คุณจำเป็นต้องทำสิ่งนี้เป็นกลุ่มหรือไม่? - person Andrew; 07.12.2019
comment
ใช่ @Andrew เรียงตามกลุ่ม (ID) เสมอตามปี - person SimoneG; 07.12.2019