2015-11-19 68 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 
})