2014-01-30 60 views
4

如何使函數根據需要使用一對或多對值(x1,y1; x2,y2; ...)子集等根據數據的一個或多個值創建子集函數。框架

selection <- function(x1,y1, ...){ 
       dfselected <- subset(df, V1 == "x1" & V2 == "y1" 
       ## MAY OR MAY NOT BE PRESENT ## 
             | V1 == "x2" & V2 == "y2") 
       return(dfselected) 
            } 

一個數據幀I可以與subset()做到這一點對一個單一的索引。例如:

df <- data.frame(
     V1 = c(rep("a",5), rep("b",5)), 
     V2 = rep(c(1:5),2), 
     V3 = c(101:110) 
       ) 

V1 V2 V3 
a 1 101 
a 2 102 
a 3 103 
a 4 104 
a 5 105 
b 1 106 
b 2 107 
b 3 108 
b 4 109 
b 5 110 

而對夫婦( 「一」, 「3」)的子集和( 「B」, 「4」)的外觀喜歡

dfselected <- subset(df, V1 == "a" & V2 == 3 | V1 == "b" & V2 == 4) 

我找不到類似的功能。我不知道是否必須將一個未指定數量的參數傳遞給一個函數(所謂的「三點」)或使用if/else。我是一名初學者,所以我們也歡迎鏈接或例子。 我開始主要是與:http://www.ats.ucla.edu/stat/r/library/intro_function.htm

------------------------------解決方案哈德利的答覆後

selection <- function (x,y){ 
          match <- data.frame(
               V1 = x, 
               V2 = y, 
               stringsAsFactors = FALSE 
               ) 
          return(dplyr::semi_join(df, match)) 
          } 

回答

3

這聽起來像你想要半聯接:查找X中有y中匹配的條目的所有行:

df <- data.frame(
    V1 = c(rep("a",5), rep("b",5)), 
    V2 = rep(c(1:5), 2), 
    V3 = c(101:110), 
    stringsAsFactors = FALSE 
) 

match <- data.frame(
    V1 = c("a", "b"), 
    V2 = c(3L, 4L), 
    stringsAsFactors = FALSE 
) 

library(dplyr) 
semi_join(df, match) 
+0

太好了!我把它在一個函數中打開(請參閱我的問題的編輯) – nebi

2

除非我失去了一些東西,你可以只使用基礎R的merge()

通過這兩個例子data.frames哈德利提供,

merge(df, match) 
# V1 V2 V3 
# 1 a 3 103 
# 2 b 4 109 
+0

我認爲合併將在大多數情況下都能正常工作,但我不確定其在x或y中行重複的邊緣情況下的行爲。 – hadley

+1

@hadley - 據我所見,它工作得很好。要看它如何處理重複的行,只需要:'df2 < - rbind(df,df [9,]); match2 < - 匹配[c(1,1,1,2),]'。然後,根據你想如何處理'match2'中的重複行,執行'merge(df2,match2)'或'merge(df2,unique(match2))'。 –

+0

如果你有兩個重複的行?它是否做笛卡爾產品?我確信我有一些原因,我做了'semi_join()':/(除了名字的速度和通信價值) – hadley

相關問題