使用以id为条件的零替换R数据帧中的NA

时间:2014-03-07 08:45:19

标签: r dataframe na

我有一个有几个NA的data.frame。我已经知道,如果某个公司的某个列的值为零,那么这些NAs也是零。什么是用零替换那些和只有那些NA的好方法。

一个例子:

我想改变这个

  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

编辑:变量的数量可能很大,因此我想找到一种方法同时将这个整齐地应用于所有变量,而无需手动输入每个变量名称。

3 个答案:

答案 0 :(得分:4)

这是另一个ddply替代方案,您无需指定应该应用该函数的变量名称。通过使用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中,我假设第一列包含分组变量(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}

答案 1 :(得分: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

答案 2 :(得分: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})

但非常不优雅

编辑:我之前的代码没有用,所以我修复了它:)