2012-06-30 56 views
1

我正在用更快的應用函數替換所有循環。我有一個問題,使功能取決於前一列。具有相同矩陣的列取決於列

目前,我需要根據考試成績,這是有可能使用

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'))}) 

但是分配了一個檔次,是可以繼續使用的應用功能和擴展的代碼,這樣不管列如果將'C'返回到該列右側的所有後續等級,則在該行中替換爲'C'。

由於一百萬

R.

+0

'apply'命令族並不總是更快。另外,如果你描述你想要的更好,我們可能會提供幫助。請告訴我們你的意圖,而不是傾銷一些我們必須解析的代碼(可能或可能實際上可能不是你想要的!) –

+0

對不起,我正在爲我的設施中的大學生彙總成績。我需要將數字等級轉換爲字母,分數在40-50 = D之間,50-60 = C之間等等。這是由上面的代碼照顧。對於課程的持續評估部分,如果學生的成績低於某個等級,學生將需要重複 - 不管後續的CA成績如何。我目前在一個循環中執行此操作,但我認爲使用apply函數可能更乾淨更快捷。感謝您的幫助,R. – user1493174

回答

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

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)) 
+0

很好的使用'match'來避免循環。 –

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")) 
) 
+0

非常好的使用'ifelse'來代替Cs。 – nograpes