2016-04-08 28 views
5

私は、セクションごとの週単位のデータを持つデータフレームを持っています。各セクションにはおよそ104週間分のデータがあり、合計で83セクションがあります。条件に基づいたデータフレーム/テーブルの結合/結合<

私はメインデータフレームをフィルタリングするセクションで開始週と終了週を持つ2番目のデータフレームを持っています。

両方の表では、週は年と週の組み合わせです。 201501及びだから私は201401 201404に週によってセクションAをフィルタリングする以下の例では数週間から1 52

に常にあり、私が最初に思った週によってセクションB 201551 201603.

に私が追加することができます(各週の各行を複製する)週の開始と終了の連続番号であるWeeks_Filterデータフレームに追加列を追加し、2つのテーブルをマージし、すべてのデータをWeeks_Filterテーブル(すべて。 y = TRUE)これは小さなサンプルでも有効でしたが、別の年にまたがることがあるので、連続した週を追加する方法はわかりません。

Week <- c("201401","201402","201403","201404","201405", "201451", "201552", "201601", "201602", "201603") 
Section <- c(rep("A",5),rep("B",5)) 
df <- data.frame(cbind(Week, Section)) 

Section <- c("A", "B") 
Start <- c("201401","201551") 
End <- c("201404","201603") 
Weeks_Filter <- data.frame(cbind(Section, Start, End)) 

答えて

-2
require(data.table) 

df <- merge(df, Weeks_Filter) 
df[, -1] <- apply(df[, -1], 2, function(x) as.numeric(as.character(x))) 
df <- data.table(df) 

df[Week >= Start & Week <= End, .SD, by = Section] 

出力がdata.tableの最新development versionが非エクイが合流追加(と古いものにごfoverlapsを使用することができます)、

Section Start End Week 
1:  A 201401 201404 201401 
2:  A 201401 201404 201402 
3:  A 201401 201404 201403 
4:  A 201401 201404 201404 
5:  B 201551 201603 201552 
6:  B 201551 201603 201601 
7:  B 201551 201603 201602 
8:  B 201551 201603 201603 
+0

ありがとうございます。それは完璧に働いた。 – MidnightDataGeek

+0

私は、なぜ答えが投票になっているのだろうと思っています。人々はより単純なものではなく、複雑な解決策を好みますか? – TheRimalaya

+0

答えは私のためにうまくいきました。私はRに新しく、下に提供されているリンクを使用していても、答えを得ることができませんでした。 – MidnightDataGeek

1

あなたは

  • は、開始と終了の列に基づいて、セクションで、あなたのデータフレーム
  • フィルタを
  • グループを組み合わせることができdplyrを使用

一つの問題は、ということですあなたの "週は文字であり、あなたがそれらをエンコードした方法の要素になります。私はショートカットを作成して数値にしましたが、lubridateを使用して、これらの適切なDateクラスベクトルを作成することをお勧めします。

library(dplyr) 
tempdf <- full_join(df, Weeks_Filter) 
tempdf$Week <- as.numeric(as.character(tempdf$Week)) 
tempdf$Start <- as.numeric(as.character(tempdf$Start)) 
tempdf$End <- as.numeric(as.character(tempdf$End)) 


tempdf_filt <- tempdf %>% 
    group_by(Section) %>% 
    filter(Week >= Start, 
     Week <= End) 

それは「201451」は「201551」であることを、あなたのデータに問題がありますように見えますが、それ以外、あなたが望むものを返します。おそらく、すべての希望週のベクトルを作成

> tempdf_filt 
Source: local data frame [8 x 4] 
Groups: Section [2] 

    Week Section Start End 
    (dbl) (fctr) (dbl) (dbl) 
1 201401  A 201401 201404 
2 201402  A 201401 201404 
3 201403  A 201401 201404 
4 201404  A 201401 201404 
5 201552  B 201551 201603 
6 201601  B 201551 201603 
7 201602  B 201551 201603 
8 201603  B 201551 201603 
+1

年には52を持っています – eddi

+0

@ johnSGありがとうございました - 私はそこにタイプミスがありました。私はdata.tableをマスターしようとしていますので、これを使用しましたが、これもうまくいきました。 – MidnightDataGeek

+0

@eddi私はタイプミス(カルマ)を指摘していました。 201501 - > 201551.修正されました – JohnSG

0

が働くだろうフィルターのために。ここでは基本Rを使用して大まかな例である:

# get weeks 
allWeeks <- as.character(1:52) 
allWeeks <- ifelse(nchar(allWeeks)==1, paste0("0",allWeeks), allWeeks) 
# get all year-weeks 
allWeeks <- paste0(2014:2015, allWeeks) 

# filter vector to select desired weeks 
keepWeeks <- keepWeeks[grep("201(40[1-4]|55[12]|60[123]))", allWeeks)] 

dfKeeper <- df[df$Week %in% keepWeeks,] 

私はあなたが欲しいの期間をキャプチャするだろう正規表現を構築しようとしましたが、あなたはそれを少し調整する必要があります。

4

です:

setDT(df) # convert to data.table in place 
setDT(Weeks_Filter) 

# fix the column types - you have factors currently, converting to integer 
df[, Week := as.integer(as.character(Week))] 
Weeks_Filter[, `:=`(Start = as.integer(as.character(Start)), 
        End = as.integer(as.character(End)))] 

# the actual magic 
df[df[Weeks_Filter, on = .(Section, Week >= Start, Week <= End), which = T]] 
#  Week Section 
#1: 201401  A 
#2: 201402  A 
#3: 201403  A 
#4: 201404  A 
#5: 201552  B 
#6: 201601  B 
#7: 201602  B 
#8: 201603  B 
+4

また、 'x.'という接頭辞を使用することもできます(特にxの結合列を参照するのに便利です)' df [Weeks_Filter、。(x.Week、Section)、on =(Section、Week> = Start、Week < = End)] ' – Arun

+0

@eddi返信ありがとうございます。私はあなたの答えを複製することができませんでした、私はこれが同じバージョンのdata.tableを持っていないためだと思います。私が持っていたエラーは:機能を見つけることができませんでした "。 – MidnightDataGeek

+0

最新のバージョンを入手するには、回答のリンクを使用してください。 – eddi