2012-12-06 156 views
1

我想用另一個數據幀中的匹配計數向列中添加一列,這看起來很平凡,但我不能似乎得到它的工作。例如:在一個數據幀中添加一個計數列與另一個數據幀中匹配的計數

smaller_df$CountOfMatches <- nrow(subset(larger_df, Date == smaller_df$Date)) 

這給我的錯誤:

In `==.default`(Date, smaller_df$Date) : 
    longer object length is not a multiple of shorter object length 

我知道的數據幀的長度不同,我不要求用於合併,我只需要爲每一行/日(有效的日期對象)在smaller_df中;計算在large_df中有多少匹配。

我對R非常陌生,所以一定有一些基本的和非常微不足道的東西。

在此先感謝

+0

我有什麼工作,它很醜陋,我敢肯定有一個更好的解決辦法,所以我覺得這個問題是仍然有效。我的破解是:smaller_df $ CountOfMatches < - apply(smaller_df,1,function(row){nrow(subset(larger_df,Date == row [1]))}) – gatapia

回答

4

這裏是什麼似乎相當簡單:

smaller_df$bigDfCount <-sapply(smaller_df$Date, 
         FUN=function(x) length(larger_df[larger_df$Date==x, "Date"])) 
smaller_df 

     Date bigDfCount 
1 2000-01-01   4 
2 2000-01-02   2 
3 2000-01-03   5 
4 2000-01-04   4 
5 2000-01-05   5 
6 2000-01-06   6 
7 2000-01-07   2 
8 2000-01-08   5 
9 2000-01-09   3 
10 2000-01-10   3 
+1

我可能會用'sapply(smaller_df $ Date,function(Dt){sum(larger_df $ Date == Dt)})',但是真的一樣。 –

+1

如果你添加了',na.rm == TRUE',那麼你的可能會比其中任何一個更好。 –

+0

非常好,乾淨整潔 – gatapia

4

這是最簡單的創建一個彙總表,然後合併,在與你原來的(小)的數據。有一個可重複的例子更好。因此,這裏是一些重複性的數據:

smaller_df <- data.frame(Date=seq(as.Date("2000-01-01"), 
            as.Date("2000-01-10"), by="1 day")) 
set.seed(5) 
larger_df <- data.frame(Date=sample(seq(as.Date("2000-01-01"), 
             as.Date("2000-01-20"), by="1 day"), 
            80, replace=TRUE)) 

創建日期表(計數)在larger_df

tbl <- table(larger_df$Date) 

將它轉換爲一個data.frame適合合併

counts <- data.frame(Date=as.Date(names(tbl)), CountOfMatches=as.vector(tbl)) 

然後在日期合併。請注意,如果日期未出現在larger_df中,但在smaller_df中出現,則CountOfMatches將爲NA,而不是0

merge(smaller_df, counts, all.x=TRUE) 

對於此樣本數據,你會得到

> merge(smaller_df, counts, all.x=TRUE) 
     Date CountOfMatches 
1 2000-01-01    4 
2 2000-01-02    2 
3 2000-01-03    5 
4 2000-01-04    4 
5 2000-01-05    5 
6 2000-01-06    6 
7 2000-01-07    2 
8 2000-01-08    5 
9 2000-01-09    3 
10 2000-01-10    3 

編輯:

它使用一個包(它提供了擺脫一些轉換細節的方便功能的更簡潔版本)是

library("plyr") 
merge(smaller_df, 
     ddply(larger_df, .(Date), summarise, CountOfMatches=length(Date)), 
     all.x = TRUE) 

相同的結果和實際上相同的邏輯。關於不在larger_df中的日期也是同樣的警告。

+0

我想我會將它標記爲答案(給它一天),儘管我仍然不高興。對我而言,目前的兩種解決方案看起來都很複雜,儘管它可能是我尋求程序化解決方案的迫切需要。從數據框到表格到數據框的所有這些轉換對我來說都很難看。我明白,這可能是我個人的偏見(對R方式是新的)。無論如何,我更喜歡這個加載一個額外的包作爲建議anoop。 – gatapia

4

有一種使用data.table包的方法。這是一個用於在內存中高效處理大型數據集的包,允許類似SQL或SAS的數據類似於步驟操作,但方括號[]與data.frame對象的行爲不同。你可以在[]中放入data.table連接,表達式和聚合。閱讀data.table手冊瞭解更多信息。

首先,將您的兩個幀轉換爲data.table對象,並將鍵列設置爲Date。 data.table對象將按日期排序,然後可以連接。

使用相同的樣本數據如上:

library(data.table) 
smaller_df <- data.table(data.frame(Date=seq(as.Date("2000-01-01"), 
    as.Date("2000-01-10"), by="1 day"))) 
set.seed(5) 
larger_df <- data.table(data.frame(Date=sample(seq(as.Date("2000-01-01"), 
    as.Date("2000-01-20"), by="1 day"), 80, replace=TRUE))) 

設置鍵列是日期:

setkey(smaller_df, Date) 
setkey(larger_df, Date) 

可以使用通過,而無需按語法和使用你的事實按日期鍵入。 .N將返回子集中的行數(即日期匹配的行數)。

larger_df[smaller_df, .N] 
##   Date N 
## 1: 2000-01-01 4 
## 2: 2000-01-02 2 
## 3: 2000-01-03 5 
## 4: 2000-01-04 4 
## 5: 2000-01-05 5 
## 6: 2000-01-06 6 
## 7: 2000-01-07 2 
## 8: 2000-01-08 5 
## 9: 2000-01-09 3 
## 10: 2000-01-10 3 
相關問題