2014-03-07 64 views
2

我有一個data.frame有幾個NAs。我已經知道,如果某列的某個公司的某個值爲零,那麼這些NAs也是零。用零代替那些並且只有那些NAs是一種好方法。替換R數據框中的NAs,條件爲ID爲零

一個例子:

我想要改造這個

FIRMID VAR1  VAR2   
    FIRM1  0  1 
    FIRM1  NA  NA 
    FIRM2  1  0 
    FIRM2  NA  NA 

這個

FIRMID VAR1  VAR2   
    FIRM1  0  1 
    FIRM1  0  NA 
    FIRM2  1  0 
    FIRM2  NA  0 

編輯:變量數目可能是大的,所以我想找到一種方法,適用這對所有人都很好,同時不需要手動輸入每個變量名稱。

+0

「VAR1」,「VAR2」的值總是:0,1,NA? – zx8754

+0

他們是新手,零和非零。所以1只是一個代表非零的例子。 – Antti

回答

4

這裏是另一個ddply替代,你不必指定變量名,其功能應b應用於。通過使用numcolwise,該功能可對所有數字列進行操作。

library(plyr) 

myfun <- function(x){ 
    x[is.na(x) & (sum(!is.na(x) & x == 0) > 0)] <- 0 
    x} 

ddply(df, .(FIRMID), numcolwise(myfun)) 

# FIRMID VAR1 VAR2 
# 1 FIRM1 0 1 
# 2 FIRM1 0 NA 
# 3 FIRM2 1 0 
# 4 FIRM2 NA 0 

或者在base R,其中I假設第一列包含分組變量(dat[ , -1])。你當然可以用名字來引用它。

df2 <- do.call(rbind, by(df, df[ , "FIRMID"], function(dat){ 
    sapply(dat[ , -1], function(x){ 
    myfun(x) 
    }) 
})) 

data.frame(FIRMID = df$FIRMID, df2) 

# FIRMID VAR1 VAR2 
# 1 FIRM1 0 1 
# 2 FIRM1 0 NA 
# 3 FIRM2 1 0 
# 4 FIRM2 NA 0 

更新 'myfun' 可以寫簡單得多。感謝@Arun的建議!

myfun <- function(x){ 
    x[is.na(x) & any(x == 0)] <- 0 
    x} 
2

你可以在這裏使用ddply。但如果data.frame非常大,則效率會非常低。如果沒有,那麼你可以嘗試:

your.data.frame<-ddply(your.data.frame,~FIRMID,function(x){ 
if (any(x[!is.na(x$VAR1),"VAR1"]==0)){x[is.na(x$VAR1),"VAR1"]<-0} 
if (any(x[!is.na(x$VAR2),"VAR2"]==0)){x[is.na(x$VAR2),"VAR2"]<-0} 
x}) 

,但很不雅觀

編輯:我的代碼之前沒有工作,所以我固定它:)

3

如果你不只有整數你可能需要調整這個比較浮點數:

DF <- read.table(text="FIRMID VAR1  VAR2   
FIRM1  0  1 
FIRM1  NA  NA 
FIRM2  1  0 
FIRM2  NA  NA", header=TRUE) 

na_replace <- function(x) { 
    if (any(na.omit(x)==0L)) x[is.na(x)] <- 0L 
    x 
} 

library(plyr) 
ddply(DF, .(FIRMID), transform, 
     VAR1=na_replace(VAR1), 
     VAR2=na_replace(VAR2)) 

# FIRMID VAR1 VAR2 
#1 FIRM1 0 1 
#2 FIRM1 0 NA 
#3 FIRM2 1 0 
#4 FIRM2 NA 0