我希望在R中的数据框上执行这种简单的分类。类别是1,2,3,4和-1。我希望将此计算的结果添加到数据框中的新列。 “oldCol”是数据框中已有的列的名称。
DF$newCol <- apply(DF, 1, function(row) {
if (row[["oldCol"]] > 10.0)
{result1 <- 4.0}
else if (row[["oldCol"]] > 2.0 && row[["oldCol"]] <= 10.0)
{result1 <- 3.0}
else if (row[["oldCol"]] > 0.5 && row[["oldCol"]] <= 2.0)
{result1 <- 2.0}
else if (row[["oldCol"]] > 0.0 && row[["oldCol"]] <= 0.5)
{result1 <- 1.0}
else
{result1 <- -1.0}
return(result1)
})
我的问题:代码确实创建了一个新列,但其中的值不正确!使用这个确切的代码,超过10的数字被正确分类为类4,但所有其他行包含-1。为什么?算法非常简单,这真让我烦恼。
另外,有更优雅的方法吗?
答案 0 :(得分:3)
您的代码适合我:
DF <- data.frame(oldCol=c(-1,0.25,1,5,12))
DF$newCol <- apply(DF, 1, function(row) {
if (row[["oldCol"]] > 10.0)
{result1 <- 4.0}
else if (row[["oldCol"]] > 2.0 && row[["oldCol"]] <= 10.0)
{result1 <- 3.0}
else if (row[["oldCol"]] > 0.5 && row[["oldCol"]] <= 2.0)
{result1 <- 2.0}
else if (row[["oldCol"]] > 0.0 && row[["oldCol"]] <= 0.5)
{result1 <- 1.0}
else
{result1 <- -1.0}
return(result1)
})
结果:
## oldCol newCol
## 1 -1.00 -1
## 2 0.25 1
## 3 1.00 2
## 4 5.00 3
## 5 12.00 4
##
另一种选择:
DF <- transform(DF,
newCol=as.numeric(as.character(cut(oldCol,
breaks=c(-Inf,0,0.5,2,10,Inf),
labels=c(-1,1:4)))))
或:
library("plyr")
DF <- mutate(DF,
tmpCol=cut(oldCol,
breaks=c(-Inf,0,0.5,2,10,Inf),labels=FALSE),
newCol=ifelse(tmpCol=="1",-1,as.numeric(tmpCol)-1))
答案 1 :(得分:2)
这是一个稍微简单的答案,也考虑到你正在处理double
,因此会出现精确问题:
cuts = c(0, 0.5, 2, 10) + 1e-8 # example precision, pick appropriately for your problem
# (possibly pick a different precision for each cut point)
DF$newCol = findInterval(DF$oldCol, cuts)