[英]Replacing NAs in R dataframe with zeros conditional on an id
我有一个有几个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
编辑:变量的数量可能很大,因此我想找到一种方法将这个整齐地应用于所有这些变量,而无需手动输入每个变量名称。
这是另一个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}
如果您不只有整数,则可能需要对此进行调整以比较浮点数:
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
你可以在这里使用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})
但非常不优雅
编辑:我的代码之前没有工作,所以我修复它:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.