我必须检查data.frame中所有变量的名称,如果找到匹配,则需要用中位数替换该变量中的NA值,而其他变量则用平均值替换NAs。
data.frame cyl_spec有11个变量,我必须替换NA,如下所示:
当然,我可以通过一次选择一个变量来做到这一点,但是我尝试了以下代码:
attach(cyl_spec)
var <- colnames(cyl_spec)
for(val in var)
{
if(val == 'viscosity'){viscosity[is.na(viscosity == T)] <- median(viscosity, na.rm = T)}
else if(val == 'wax'){wax[is.na(wax == T)] <- median(wax, na.rm = T)}
else {val[is.na(val == T)] <- mean(val, na.rm = T)}
}
detach(cyl_spec)不知何故,代码没有执行任何操作,而且我仍然使用以下命令在变量中获得相同的NA值:
sum(is.na(cyl_spec$viscosity) 此外,当我运行这段代码时,我会收到以下警告消息:
Warning messages:
1: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
2: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
3: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
4: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
5: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
6: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
7: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
8: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA
9: In mean.default(val, na.rm = T) :
argument is not numeric or logical: returning NA有人能帮我找到解决这个问题的办法吗,我被困住了!提前谢谢!!
发布于 2015-07-30 08:21:09
您不需要一个循环来完成这个任务。此外,测试na值的正确语法是is.na(var),而不是is.na(var == TRUE)。最后,如果您想避免键入数据文件的名称,则需要使用一些函数(比如with或dplyr函数)。在这里,R正在寻找一个名为viscosity的对象,因为它是cyl_spec中一个列的名称(其他变量名也是如此),所以在哪里都找不到它。
cyl_spec$viscosity[is.na(cyl_spec$viscosity)] <- median(cyl_spec$viscosity, na.rm = T)
cyl_spec$wax[is.na(cyl_spec$wax)] <- median(cyl_spec$wax, na.rm = T)
cyl_spec$val[is.na(cyl_spec$val)] <- mean(cyl_spec$val, na.rm = T)如果您只需要处理这个data.frame,并且只处理这三个变量,我强烈建议您坚持这个基-r解决方案。但是,如果您希望在具有更多变量的数据框架上执行此操作,并且希望将其自动化,则可以查看dplyr::mutate_each。下面是一个有模拟数据的例子。
我们用7个变量创建一个data.frame,并分配一些NA值。
library(dplyr)
set.seed(10)
df <- data.frame(n=runif(100),
m=runif(100),
d=runif(100),
o=runif(100),
e=runif(100),
f=runif(100),
g=runif(100))
df <- mutate_each(df,funs(ifelse(.>.8,NA,.)))
head(df)
n m d o e f g
1 0.50747820 0.34434350 0.2230884 0.347860110 NA NA NA
2 0.30676851 0.06132255 0.5358950 0.007992606 0.6855115 NA 0.7478783
3 0.42690767 0.36897981 0.6625291 0.401344915 0.6296311 NA 0.7225419
4 0.69310208 0.40759356 NA 0.588350693 0.7508252 0.29063776 0.5457709
5 0.08513597 NA 0.1491831 NA NA 0.07203601 0.2641231
6 0.22543662 NA 0.6700994 0.708542599 0.3600703 0.55888842 0.3057243现在,我们对每个变量应用一个函数,从平均值或中值推断NA值:
df <- df %>%
## Which variables are to be recoded with mean? here, n and m
mutate_each(funs(ifelse(is.na(.),mean(.,na.rm = TRUE),.)),n,m) %>%
## Which variables are to be recoded with median? here, d,o,e,f,g
mutate_each(funs(ifelse(is.na(.),median(.,na.rm = TRUE),.)),d,o,e,f,g)
head(df)
n m d o e f g
1 0.50747820 0.34434350 0.2230884 0.347860110 0.3602354 0.39956699 0.4499041
2 0.30676851 0.06132255 0.5358950 0.007992606 0.6855115 0.39956699 0.7478783
3 0.42690767 0.36897981 0.6625291 0.401344915 0.6296311 0.39956699 0.7225419
4 0.69310208 0.40759356 0.4407363 0.588350693 0.7508252 0.29063776 0.5457709
5 0.08513597 0.40892568 0.1491831 0.378731867 0.3602354 0.07203601 0.2641231
6 0.22543662 0.40892568 0.6700994 0.708542599 0.3600703 0.55888842 0.3057243发布于 2015-07-30 10:48:42
尽管@scoa已经回答了,但是如果您仍然希望使用for循环来完成这个任务,只需去掉attach和detach函数,然后执行以下操作:
var <- names(cyl_spec) #get column names
cols <- c('viscosity', 'wax') #get the required columns
for(val in var)
{
#loop over the required columns.
# Where it equals our required, use median, and mean elsewhere
for(i in 1:length(cols))
{
if(is.element(cols[i], val))
{
#get out rows with na values
na_rows <- is.na(cyl_spec[, val])
cyl_spec[na_rows,val] <- median(cyl_spec[,val], na.rm = T)
}
else
{
#get out rows with na values
na_rows <- is.na(cyl_spec[, val])
cyl_spec[na_rows,val] <- mean(cyl_spec[,val], na.rm = T)
}
}
}正如您可能看到的那样,...though非常麻烦。强烈建议您直接输入它们,如@scoa提供的问题和答案,或者当您有超过2列想要更改时。(还研究如何在mutate包中使用dplyr函数)。
https://stackoverflow.com/questions/31718436
复制相似问题