2013-12-20 63 views
3

我有元素的列表清單說:[R編程:創建配對的元素

l <- c("x","ya1","xb3","yb3","ab","xc3","y","xa1","yd4") 

出這份名單的,我想使匹配X,Y對的列表,即

(("xa1" "ya1") ("xb3" "yb3") ("x" "y")) 

從本質上說,我需要捕捉的X元素,在Y元素,然後將它們配對起來: 我知道該怎麼做了X,Y提取部分:

xelems <- grep("^x", l, perl=TRUE, value=TRUE) 
yelems <- grep("^y", l, perl=TRUE, value=TRUE) 

了一個Y元素的X元素對當

1. xElem == yElem # if xElem and yElem are one char long, i.e. 'x' and 'y'  
2. substr(xElem,1,nchar(xElem)) == substr(yElem,1,nchar(yElem)) 

沒有秩序的,即匹配xElem和yElem可以定位在任何位置。

但是我不太確定下一部分。我比較熟悉的SKILL programming language(技能是一個LISP衍生物),這是我寫的:

procedure(get_xy_pairs(inputList "l") 
    let((yElem (xyPairs nil) xList yList) 
    xList=setof(i inputList rexMatchp("^x" i)) 
    yList=setof(i inputList rexMatchp("^y" i)) 
    when(xList && yList 
     unless(length(xList)==length(yList) 
    warn("xList and yList mismatch : %d vs %d\n" length(xList) length(yList)) 
    ) 
     foreach(xElem xList 
     if(xElem=="x" 
      then yElem="y" 
      else yElem=strcat("y" substring(xElem 2 strlen(xElem))) 
     ) 
     if(member(yElem yList) 
      then xyPairs=cons(list(xElem yElem) xyPairs) 
      else warn("x element %s has no matching y element \n" xElem) 
     ) 
    ) 
    ) 
    xyPairs 
) 
) 

當L RUN,這將返回

get_xy_pairs(l) 
*WARNING* x element xc3 has no matching y element 
(("xa1" "ya1") ("xb3" "yb3") ("x" "y")) 

正如我還是新R,如果你們可以幫忙,我會很感激。此外,我確實瞭解R族人傾向於避免循環,並且更傾向於lapply?

Thx提前。 Riad。

回答

3

也許這樣的事情會工作。 (只有在你的樣本數據進行測試)

## Remove any item not starting with x or y 
l2 <- l[grepl("^x|^y", l)] 

## Split into a list of items starting with x 
## and items starting with y 
L <- split(l2, grepl("^x", l2)) 

## Give "names" to the "starting with y" group 
names(L[[1]]) <- gsub("^y", "x", L[[1]]) 

## Use match to match the names in the y group with 
## the values from the x group. This results in a 
## nice named vector with the pairs you want 
Matches <- L[[1]][match(L[[2]], names(L[[1]]), nomatch=0)] 
Matches 
#  x xb3 xa1 
# "y" "yb3" "ya1" 

作爲data.frame

MatchesDF <- data.frame(x = names(Matches), y = unname(Matches)) 
MatchesDF 
#  x y 
# 1 x y 
# 2 xb3 yb3 
# 3 xa1 ya1 
+0

阿南達,非常感謝你的解決方案,完美的作品! – Riad

1

我將存儲在元組的列表,即:

xypairs 
[[1]] 
[1] "x" "y" 

[[2]] 
[2] "xb3" "yb3" 

你的程序也可以與matchsubstring簡化。

xends <- substring(xelems, 2) 
yends <- substring(yelems, 2) 
ypaired <- match(xends, yends) # Indices of yelems that match xelems 

# Now we need to handle the no-matches: 
xsorted <- c(xelems, rep(NA, sum(is.na(ypaired)))) 
ysorted <- yelems[ypaired] 
ysorted <- c(ysorted, yelems[!(yelems %in% ysorted)]) 

# Now we create the list of tuples: 
xypairs <- lapply(1:length(ysorted), function(i) { 
    c(xsorted[i], ysorted[i]) 
}) 

結果:

xypairs 
[[1]] 
[1] "x" "y" 

[[2]] 
[1] "xb3" "yb3" 

[[3]] 
[1] "xc3" NA 

[[4]] 
[1] "xa1" "ya1" 

[[5]] 
[1] NA "yd4" 
+0

Manetheran,THX很多關於你的貢獻,非常感謝! – Riad