我有一个数据框mydata,构造如下:
col1<-c(8.20e+07, 1.75e+08, NA, 4.80e+07,
3.40e+07, NA, 5.60e+07, 3.00e+06 )
col2<-c(1960,1960,1965,1986,1960
,1969,1960,1993)
col3<-c ( NA,2.190,NA,NA, 5.000, NA,
1.700,4.220)
mydata<-data.frame(col1,col2,col3)
mydata
# col1 col2 col3
# 1 8.20e+07 1960 NA
# 2 1.75e+08 1960 2.19
# 3 NA 1965 NA
# 4 4.80e+07 1986 NA
# 5 3.40e+07 1960 5.00
# 6 NA 1969 NA
# 7 5.60e+07 1960 1.70
# 8 3.00e+06 1993 4.22
我想创建一个col4
,其值为"a", "b" and "c"
,
如果col1
小于4.00e + 07,则col4=="a"
;如果col1
不小于4.00e + 07,则为col4=="b"
,否则为col4=="c
&#34;
这是我的代码:
col4 <-ifelse(col1<4.00e+07, "a",
ifelse(col1 >=4.00e+07, "b",
ifelse(is.na(col1 =4.00e+07), "b", "c" )))
但评估结果为:
# [1] "b" "b" NA "b" "a" NA "b" "a"
它不会将col1中的NA值更改为&#34; c&#34;。
结果应该是:
# [1] "b" "b" "c" "b" "a" "c" "b" "a"
我的代码有什么问题?任何建议将不胜感激!
答案 0 :(得分:6)
您必须先检查is.na
,因为NA < 4.00e+07
会导致NA
。如果ifelse()
的第一个参数为NA
,则结果也为NA
:
ifelse(c(NA, TRUE, FALSE), "T", "F")
## [1] NA "T" "F"
如您所见,对于第一个向量元素,结果确实是NA
。即使ifelse()
的其他参数具有可以处理这种情况的特殊代码,它也无济于事,因为该代码永远不会被考虑在内。
对于您的示例,首先检查NA
会为您提供所需的结果:
col4 <- ifelse(is.na(col1), "c",
ifelse(col1 < 4.00e+07, "a","b"))
col4
## [1] "b" "b" "c" "b" "a" "c" "b" "a"
答案 1 :(得分:3)
这也可以通过cut
v1 <- with(mydata, as.character(cut(col1,
breaks=c(-Inf, 4.00e+07, Inf), labels=c("a", "b"))))
v1[is.na(v1)] <- "c"
v1
#[1] "b" "b" "c" "b" "a" "c" "b" "a"