我有一个有几个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
编辑:变量的数量可能很大,因此我想找到一种方法同时将这个整齐地应用于所有变量,而无需手动输入每个变量名称。
答案 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})
但非常不优雅
编辑:我之前的代码没有用,所以我修复了它:)