![](/img/trans.png)
[英]Replacing NA values for a variable in a dataframe with non-NA values from prior rows conditional on values of another variable
[英]Setting a value in a variable to NA, conditional on another variable
如果滿足另一個變量的條件,我想刪除變量中的值。 例如:
df$var1[df$condvar == 0] <- NA
上面的代碼工作正常,但我需要重復幾十個變量,所以上面的var1
會改變為var2
, var3
等。這總是基於相同的condvar
,盡管有一半的變量條件是df$condvar == 1
。 一遍又一遍地重復這一行是很麻煩的,我想知道是否有更簡潔的方法來編寫代碼。 其中一個apply
函數是否有幫助,或者我是否需要創建自定義函數?
作為一個可重復的例子,我希望避免下面代碼的重復性:
ex <- mtcars
ex$mpg[ex$vs == 0] <- NA
ex$disp[ex$vs == 0] <- NA
ex$drat[ex$vs == 0] <- NA
ex$cyl[ex$vs == 1] <- NA
ex$hp[ex$vs == 1] <- NA
ex$wt[ex$vs == 1] <- NA
ex
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 NA 6 NA 110 NA 2.620 16.46 0 1 4 4
Mazda RX4 Wag NA 6 NA 110 NA 2.875 17.02 0 1 4 4
Datsun 710 22.8 NA 108.0 NA 3.85 NA 18.61 1 1 4 1
Hornet 4 Drive 21.4 NA 258.0 NA 3.08 NA 19.44 1 0 3 1
Hornet Sportabout NA 8 NA 175 NA 3.440 17.02 0 0 3 2
Valiant 18.1 NA 225.0 NA 2.76 NA 20.22 1 0 3 1
Duster 360 NA 8 NA 245 NA 3.570 15.84 0 0 3 4
etc.
如果有一行代碼適用於condvar == 0
所有變量而另一行適用於condvar == 1
變量,我會非常高興。
這是一次希望不太復雜的嘗試。 如果設置要循環的vars
,並且要為索引選擇相應的values
,則可以執行以下操作:
vars <- c("mpg", "disp", "cyl", "hp")
values <- c(0, 0, 1, 1)
ex[vars] <- Map(function(x,y) replace(x, ex$vs == y, NA), ex[vars], vals)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 NA 6 NA 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag NA 6 NA 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 NA 108.0 NA 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 NA 258.0 NA 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout NA 8 NA 175 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 NA 225.0 NA 2.76 3.460 20.22 1 0 3 1
# ...
如果你只有兩個組,你可以通過注釋中提到的@HubertL和@Phil等幾個賦值來更簡單,但是使用Map
可以考慮許多帶有許多可能索引值的變量,而不會超過3行代碼
感謝@HubertL(歡迎發布此作為答案,我將贊成)和@smci:
ex[ex$vs == 0, c("mpg", "disp", ...)] <- NA
ex[ex$vs == 1, c("cyl", "hp", ...)] <- NA
使用新的實驗case_when
函數的dplyr方法將類似於:
require(dplyr)
ex <- mtcars
ex <- ex %>%
mutate(mpg = case_when(.$vs==0 ~ as.double(NA), TRUE ~ .$mpg)) %>%
mutate(disp = case_when(.$vs==0 ~ as.double(NA), TRUE ~ .$disp)) %>%
mutate(cyl = case_when(.$vs==1 ~ as.double(NA), TRUE ~ .$cyl)) %>%
mutate(hp = case_when(.$vs==1 ~ as.double(NA), TRUE ~ .$hp))
筆記:
case_when
工作,它會很好。 同時filter()
的解決方法如下 .$var
來引用RHS上的變量 as.double(NA)
TRUE ~ ...
指定默認子句 使用filter()
工作方法:
ex <- rbind(ex %>% filter(vs==0) %>% mutate(mpg=NA, disp=NA),
ex %>% filter(vs==1) %>% mutate(cyl=NA, hp=NA) )
由於vs
的分裂,它具有重新排列行的副作用
嘗試:
ifelse(df$var1 == 0, NA, df$var1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.