2016-12-24 15 views
0

データフレームをループして、3つの列の値(2つのタイムスタンプと1つのラベル)を読み取る必要があります。次に、この3つの値の行について、2番目のデータフレームの各行と比較して、A)ラベルが一致するかどうかを確認し、B)2番目のデータフレームにあるタイムスタンプが現在の行の2つのタイムスタンプの間にあるかどうかを確認する必要があります。行が実際にこれらの2つの基準に一致する場合は、後続の処理のためにデータフレーム/ベクトルに保存する必要があります。データフレームの各行について、別のデータフレームをループする

私はx_apply関数の多くのバージョンをforループ( 'second'繰り返し)と組み合わせて試しました。以下は私の問題の非常に単純化されたバージョンです。ここで2つの小さなデータフレームを作成し、必要なループを確立しようとしています。値は 'x'に保存する必要があります。ループ内でprint(x)を実行するとこの値が表示されますが、適用機能が完了するとNULLが返されます。関数が呼び出されるたびにリセットされるようです。私の要件を考慮に入れると、違う/より良いアプローチのアイデアはありますか?私はそれ自体を適用する必要はありません。事前にどうもありがとうございました!

label <- c("p1", "p1", "p2") 
value_1 <- c(8,4,2) 
value_2 <- c(10,6,9) 
df1 <- data.frame(label, value_1, value_2) 

label <- c("p1", "p2", "p2") 
value_3 <- c(8,8,8) 
df2 <- data.frame(label, value_3) 

x = NULL 

small_function <- function(value_1, value_2, label) { 
    for(i in 1:nrow(df2[df2$label == label,])) { 
    print(i) 
    x <- append(x, i) 
    print(x) 
    } 
} 

apply(df1, 1, function(x,y,z) small_function(df1$value_1, df1$value_2, df1$label)) 
x 

更新:時間の日付を含む例で、「単一の値を期待しています」というエラーが発生します。

label <- c("p1", "p1", "p2") 
value_1 <- c(as.POSIXct(1482645600, origin="1970-01-01"),as.POSIXct(1482745600, origin="1970-01-01"),as.POSIXct(1482845600, origin="1970-01-01")) 
value_2 <- c(as.POSIXct(1582645600, origin="1970-01-01"),as.POSIXct(1582745600, origin="1970-01-01"),as.POSIXct(1582845600, origin="1970-01-01")) 
df1 <- data.frame(label, value_1, value_2) 
label <- c("p1", "p2", "p2") 
value_3 <- c(as.POSIXct(1582645100, origin="1970-01-01"),as.POSIXct(1582745200, origin="1970-01-01"),as.POSIXct(1582845300, origin="1970-01-01")) 
df2 <- data.frame(label, value_3) 

df_merge = merge(df1, df2, c("label"), suffixes = c(".df1",".df2")) 
setDT(df_merge) 
str(df_merge) 
a <- df_merge[between(value_3, value_1, value_2), ] 
+2

は、最初のマージあなたの範囲条件を適用する! –

答えて

1

これはあなたが探しているものですか?データ内のいくつかの日付と

library(data.table) 
setDT(df1) 
setDT(df2)  
setkey(df1, label) 
setkey(df2, label) 
df1[df2] # here i merge both the data.table 

df3[between(value_3, value_1, value_2), ] # apply the condition 
# label value_1 value_2 value_3 
#1: p1  8  10  8 
#2: p2  2  9  8 
#3: p2  2  9  8 

# ensure the dates are in proper formats(i had simulated some sample data with dates. just sharing the last 2 steps output) 
df3$value_1 = as.Date(df3$value_1, format= "%d/%m/%Y") 
df3$value_2 = as.Date(df3$value_2, format= "%d/%m/%Y") 
df3$value_3 = as.Date(df3$value_3, format= "%d/%m/%Y") 
# df3 
# label value_1 value_2 value_3 
#1: p1 2016-03-10 2016-03-20 2016-03-15 
#2: p1 2016-06-17 2016-06-19 2016-03-15 
#3: p2 2016-09-10 2016-09-20 2016-06-21 
#4: p2 2016-09-10 2016-09-20 2016-09-12 

df3[between(value_3, value_1, value_2), ] 
# label value_1 value_2 value_3 
#1: p1 2016-03-10 2016-03-20 2016-03-15 
#2: p2 2016-09-10 2016-09-20 2016-09-12 
+1

これは素晴らしいことです! 私はPOSIXct値の呼び出しを使用していますが、エラーが発生します。「エラー:単一の値が必要です」。どのように私はこれを解決することができる任意のアイデア? – WalterB

+1

サンプルデータを日付と共有するのは心配ですか?私はそれを調べます。それは簡単な修正になります。メリークリスマス...今教会に行く –

+0

おかげさまで素晴らしいクリスマスもあります。私はいくつかのサンプルデータを含むアップデートで私の最初の質問を編集しました。ご助力ありがとうございます。 – WalterB

1

ここでは、これはあなたが探しているものであれば、基本Rで非常に短いソリューションです:

dfr <- merge(df1, df2, by="label", all=FALSE) 
subset(dfr, value_3 > value_1 & value_3 < value_2) 
関連する問題