我正在用更快的应用函数替换所有循环。我有一个问题,使该功能依赖于前一列。
目前,我需要根据考试成绩分配成绩,这可以使用
data <- matrix(runif(100),20,5)
colnames(data) <- letters[1:5]
sapply(colnames(data),function(x){
ifelse((data[,x] <= 0 & data[,x] < 0.50),'C',
ifelse((data[,x] >= 0.50 & data[,x] < 0.70) ,'B','A'))})
但是,是否可以继续使用apply函数并扩展代码,以便无论返回“C”的列如何,该列右侧的所有后续成绩都将替换为该行中的“C”
万分感谢
R上。
答案 0 :(得分:2)
首先,您当前的代码中不需要任何循环或ifelse
;只需使用cut
:
as.character(cut(data,c(0,0.5,0.7,1),labels=c("C","B","A"),right=FALSE))->cdata
dim(data)->dim(cdata);cdata->data
你的第二个问题(在第一个“C”之后用“C”填充所有单元格)需要一个循环,可以像这样完成:
t(apply(data,1,function(x)
ifelse(seq(along=x)<min(c(which(x=="C"),Inf)),x,"C"))
)
答案 1 :(得分:1)
请尝试使用ifelse
,而不是使用嵌套的cut
语句。它使事情更容易阅读。例如:
# Create data
data <- matrix(runif(100),20,5)
# Assign a grade
x=apply(data, MARGIN=2, cut, breaks=c(0,0.5,0.7,1),labels=c('C','B','A'))
现在你制作重复的C函数,这有点棘手。
# Make the repeating C function.
find.c=function(x)
if ('C' %in% x)
c(
x[seq(0,match('C',x)-1)], # Everything before the first C
rep('C',length(x) - match('C',x) + 1) # After the first C
)
else x
# Run it.
t(apply(x,MARGIN=1,find.c))
答案 2 :(得分:0)
data <- matrix(runif(100),20,5)
colnames(data) <- letters[1:5]
data.let <- sapply(colnames(data),function(x){
ifelse((data[,x] <= 0 | data[,x] < 0.50),'C',
ifelse((data[,x] >= 0.50 & data[,x] < 0.70) ,'B','A'))})
# Note the change of & to | above to make your sample data work
apply( data.let, 1, replaceCs )
其中`replaceCs是一个函数,它接受一个向量并用C替换C之后的任何内容。
一个这样的例子:
replaceCs <- function(x) {
for(i in seq(2,length(x))) {
if(x[i-1]=="C") x[i] <- "C"
}
x
}
可能会有更聪明的东西用rollapply
炮制。