2015-11-19 45 views
3

相當新的R,所以這可能是一個簡單的答案。 我有一個字符列表。我想刪除最後一個字母等A變爲乙通過一個迭代它,1變成2等在R循環中迭代一個字符或數字

waferlist<-c('L2MLQ','L2MIW','L2MK0','L2ML6','L2MO2','L2MHE','L2MK4','L2MN6','L2MLM') 

for (i in waferlist) 
{ 

lastchar<-substr(i,5,6)   #Get last character 

k<-lastchar==LETTERS    #Is it a Letter 

pos<-min(which(k==TRUE))  #Find letter position and itterate 
pos<-pos+1 
pos<-LETTERS[pos] 

時遇到的問題是,如果最後一個字符是一個數字,它返回其作爲InfNA_character_,因爲它不是。

我試圖找到一種方法來選擇下面的這些非結果,但它並沒有看到它作爲TRUE/FALSE語句,所以它不起作用。有沒有另一種方法來做到這一點?

 if(pos==Inf | pos==NA_character_) 
    { 
     lastchar<-as.numeric(lastchar) 
     pos<-lastchar+1 
    } 
+1

是什麼9變成什麼? Z成爲什麼?我會分別猜出零和A,回到開始,但你應該澄清一點。 –

+0

有沒有一種簡單的方法可以回到基地36'strtoi(晶圓列表,36)+ 1' –

+0

對不起理查德,Ids的設置,所以他們永遠不會結束在9或Z,所以我不必擔心關於該 – Marcus

回答

2

爲了有效的解決方案(假設使用的是大寫字母),

res <- sapply(waferlist, function(i) { 
    out <- utf8ToInt(i) 
    out[[nchar(i)]] <- out[[nchar(i)]] + 1 
    if (out[[nchar(i)]] == 91) out[[nchar(i)]] <- 65 
    ## For 9 cycling back to 0? 
    else if (out[[nchar(i)]] == 58) out[[nchar(i)]] <- 48 
    intToUtf8(out) 
}) 
+0

感謝這很好! – Marcus

2

我們可以使用gsubfn由下一個數字或字母通過使用if/else條件替換最後一個字符。

library(gsubfn) 
gsubfn('(.)$', function(x) if(grepl('[0-9]', x)) 
    as.numeric(x)+1 else LETTERS[match(x, LETTERS)+1], waferlist) 
#[1] "L2MLR" "L2MIX" "L2MK1" "L2ML7" "L2MO3" "L2MHF" "L2MK5" "L2MN7" "L2MLN" 

Z和9的情況下作爲最後一個字符

LETTERS1 <- c(LETTERS[-1], LETTERS[1]) 
NUM <- c(1:9,0) 
gsubfn('(.)$', function(x) if(grepl('[0-9]', x)) 
    NUM[match(x, NUM)+1] else LETTERS1[match(x, LETTERS1)+1], waferlist) 
2

可以執行基R:

alphabet = c(LETTERS, 'A') 
dic  = as.character(c(0:9,0)) 

sapply(waferlist, function(w){ 
    el = gsub('.*(.{1})$','\\1',w) 

    if(is.na(as.numeric(el))) dic = alphabet 

    gsub('.{1}$', dic[pmatch(x=el, table=dic)+1], w) 
}) 

# "L2MLR" "L2MIX" "L2MK1" "L2ML7" "L2MO3" "L2MHF" "L2MK5" "L2MN7" "L2MLN" 
1

這裏是一個dplyr方式:

library(stringi) 

prefix = function(df, prefix) { 
    names(df) = paste(prefix, 
        names(df), 
        sep = "_") 
    df 
} 


letter_key = 
    data_frame(letter = 
       letters %>% 
       stri_trans_toupper) %>% 
    mutate(n = 1:n()) 

next_letter = 
    letter_key %>% 
    mutate(next_n = n + 1) %>% 
    left_join(letter_key %>% prefix("next")) 

data_frame(wafer = waferlist) %>% 
    mutate(letter = wafer %>% stri_sub(-1)) %>% 
    left_join(next_letter) %>% 
    mutate(next_character = ifelse(is.na(next_letter), 
           letter %>% 
            as.numeric %>% 
            `+`(1), 
           next_letter)) 
1

你可以轉換爲10進制,並添加1再轉換回。 Matlab具有一個dec2base功能,這個副本可能工作 - 而且必須是有這樣的基礎的轉換(或只是除了在base36)的更好的支持包

waferlist 
[1] "L2MLQ" "L2MIW" "L2MK0" "L2ML6" "L2MO2" "L2MHE" "L2MK4" "L2MN9" "L2MLZ" 

dec2base(strtoi(waferlist,36)+1, 36) 
[1] "L2MLR" "L2MIX" "L2MK1" "L2ML7" "L2MO3" "L2MHF" "L2MK5" "L2MNA" "L2MM0" 



dec2base <- Vectorize(function(x, base) 
{ 
    n<-ceiling(log(x+1, base)) 
    z <- c(0:9, LETTERS) 
    r <- vector("character", n) 
    for (j in n:1) 
    { 
     r[j] <- z[x %% base + 1] 
     if (j > 1) x <- x %/% base 
    } 
    r <- paste(r, collapse="") 
    r 
})