我无法获得for循环来分配字符串' NA'当没有其他条件得到满足时。
这就是我尝试过的......
Height <- c(1.6,3.4,0.42,n/a, 0.5,n/a,1.5,0,n/a,22.0)
Height <- matrix(Height)
h_cat <- matrix(, nrow = length(Height), ncol = 1)
for (i in 1:length(Height)){
if (Height[i]==0)
h_cat[i] <- 'NA'
if (Height[i]>0 & Height[i]<2)
print(Height[i])
h_cat[i] <- '0-2 m'
#print(h_cat[i])
if (Height[i]>=2 & Height[i]<5)
h_cat[i] <- '2-5 m'
if (Height[i]>=5 & Height[i]<10)
h_cat[i] <- '5-10 m'
if (Height[i]>=10)
h_cat[i] <- '>10 m'
else
h_cat[i] <- 'NA'
}
我去了is.na(),但也没有运气。
更新
抱歉,匆忙。数据已添加。
答案 0 :(得分:2)
当前代码存在两个主要问题。
NA == 0
来举例说明。因此,您只能在非NA条目上使用if
函数:which(!is.na(Height))
。if-else
构建的逻辑不符合意图。以下我认为实现了您的意图:
# Data needs to be numeric to check with ">"
Height[Height == "n/a", ] <- NA
Height <- as.numeric(Height)
h_cat <- matrix(, nrow = length(Height), ncol = 1)
# Can't have NA in logical tests
non_na_entries <- which(!is.na(Height))
for (i in non_na_entries) {
if (Height[i] == 0) {
h_cat[i] <- NA
} else if (Height[i] > 0 & Height[i] < 2) {
h_cat[i] <- '0-2 m'
} else if (Height[i] >= 2 & Height[i] < 5) {
h_cat[i] <- '2-5 m'
} else if (Height[i] >= 5 & Height[i] < 10) {
h_cat[i] <- '5-10 m'
} else if (Height[i] >= 10) {
h_cat[i] <- '>10 m'
} else
h_cat[i] <- NA
}
h_cat
[,1]
[1,] "0-2 m"
[2,] "2-5 m"
[3,] "0-2 m"
[4,] NA
[5,] "0-2 m"
[6,] NA
[7,] "0-2 m"
[8,] NA
[9,] NA
[10,] ">10 m"
答案 1 :(得分:0)
您的代码存在一些问题。 snoram解决了其中两个问题。您需要将NA
替换为'n/a'
,并且您不需要Height
成为matrix
。为了使代码完整回答,我将重复NA
部分。
Height <- c(1.6,3.4,0.42,n/a, 0.5,n/a,1.5,0,n/a,22.0)
Height[Height == "n/a"] <- NA
现在,像许多人所说的那样,复杂if/else
的替代方法是cut
。由于它返回类factor
的对象,我们需要重新编码其返回值。为此,我将使用包dplyr
中的函数。
library(dplyr)
h_cat <- cut(Height, c(0, 2, 5, 10, Inf))
h_cat[Height == 0] <- NA
h_cat <- recode_factor(h_cat,
'(0,2]' = '0-2 m',
'(2,5]' = '2-5 m',
'(5,10]' = '5-10 m',
'(10,Inf]' = '>10 m')
h_cat <- matrix(as.character(h_cat), ncol = 1)
h_cat
我相信这更简单易读。整洁。如果您将来必须回到此代码,您可能会发现它更容易维护。