ฉันรู้ว่ามีคำถามที่คล้ายกันอยู่หลายแห่งที่นี่ แต่ดูเหมือนจะไม่มีใครตอบคำถามที่แม่นยำที่ฉันมี
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
ฉันต้องการ zeroise ค่าของคอลัมน์ค่าสำหรับแถวที่ Key == "A" ชื่อคอลัมน์ถูกอ้างอิงผ่าน a grep
:
cols = grep("Val", names(df), value = TRUE)
โดยปกติแล้วเพื่อให้ได้สิ่งที่ฉันต้องการในกรณีนี้ฉันจะใช้data.table
สิ่งนี้:
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
และผลลัพธ์ที่ต้องการคือ:
Key Val1 Val2 Val3
1 A 0.000000 0.00000000 0
2 B -1.383814 0.55925762 2
3 A 0.000000 0.00000000 0
4 D 1.437151 0.05632773 4
5 A 0.000000 0.00000000 0
อย่างไรก็ตามในครั้งนี้ฉันต้องใช้dplyr
เพราะฉันกำลังทำงานในโครงการของทีมที่ทุกคนใช้งาน ข้อมูลที่ฉันให้ไว้เป็นตัวอย่างและข้อมูลจริงของฉันคือ> 5m แถวที่มีคอลัมน์ค่า 16 คอลัมน์ที่จะอัปเดต ทางออกเดียวที่ฉันสามารถทำได้คือใช้mutate_at
สิ่งนี้:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
อย่างไรก็ตามดูเหมือนว่าข้อมูลจริงของฉันจะช้ามาก ฉันหวังว่าจะหาทางออกที่ดีกว่าและที่สำคัญกว่าคือเร็วกว่า
ฉันได้ลองใช้หลาย ๆ ชุดโดยmap
ไม่ใช้การ!!
ใช้get
และ:=
(ซึ่งน่ารำคาญสามารถถูกหลอกลวงโดย:=
ใน data.table) ฯลฯ แต่ฉันคิดว่าฉันเข้าใจว่างานเหล่านี้ไม่ลึกพอที่จะสร้างโซลูชันที่ถูกต้อง