1

データ フレームの各要素に関数を適用しようとしています。このようなデータ フレームの簡単な例は次のとおりです。

> accts
ACCOUNT       DATE
   1     2008-03-01
   2     2009-06-17
   3     2008-07-02
   4     2009-03-15

私がする必要があるのは、このデータ フレームの各行を見て、以下に示すような大きなデータ フレームでそのアカウントを見つけることです。

> trans
ACCOUNT_NUM  TRAN_DATE
        1    2008-02-02
        2    2008-04-02
        3    2008-03-16
        3    2009-08-22
        3    2008-05-05
        6    2010-11-03
        7    2008-09-18
        4    2009-10-14
        4    2009-01-15
       10    2011-07-06

「accts」データ フレームの各行について、そのアカウントに対応する「trans」データ フレームのレコードを取得する必要があります。これには、「DATE」に最も近いがそれより前に発生した「TRAN_DATE」も含まれます。適用機能を使用しようとしました:

tranDateVector <- apply(accts, 2, getTranDate)

getTranDate <- function(x)
{
  tranDate <- subset(trans$TRAN_DATE, with(trans, ACCOUNT_NUM == x[1] & TRAN_DATE < x[2]))
  dataDiff <- x[2] - tranDate
  tranDate <- unique(date[which(dateDiff == min(dateDiff))])
  return(tranDate)
}

accts <- cbind(accts, tranDateVector)

ミニサンプルを実行すると、次のエラーが発生します。

Error in charToDate(x) : 
  character string is not in a standard unambiguous format

ただし、本格的なバージョンを実行すると、別のエラーが発生します。これは、次の行から発生していることに気付きました。

subset(trans$TRAN_DATE, with(trans, ACCOUNT_NUM == x[1] & TRAN_DATE < x[2]))

x を「accts」データ フレームの 3 行目に設定すると、次のようになります。

     x
     ACCOUNT       DATE
3       3      2008-07-02

コードの「サブセット」行を実行すると、次のエラーが発生します。これは、通常のコードで発生するエラーに対応しています。

> subset(trans$TRAN_DATE, with(trans, ACCOUNT_NUM == x[1] & TRAN_DATE < x[2]))
Error in eval(expr, envir, enclos) : 
  dims [product 1] do not match the length of object [10]
In addition: Warning message:
In eval(expr, envir, enclos) :
  Incompatible methods ("Ops.Date", "Ops.data.frame") for "<"

ご協力いただきありがとうございます。


(以下の情報は、上記への回答が提供された後に追加されました。b/c 複雑な問題があることに気付きました)

関数には、考慮する必要があることに気付いた追加の制約があり、これらにより問題がもう少し複雑になります。「accts」データ フレームには、2 つの異なるステータスがあります。

> accts <- data.frame(
+     ACCOUNT = 1:4,
+     DATE = as.Date(c("2008-03-01", "2009-06-17",
+                      "2008-07-02", "2009-03-15")),
+     STATUS = c("new", "old", "new", "old"))

「accts」フレームでは、レコードを古いものまたは新しいものとして分類できます。アカウントが「新規」である場合は、以前に指定された条件を満たす必要がありますが、「改訂済み」としてフラグが立てられた「トランザクション」内のレコードとのみ一致する必要もあります。同様に、「古い」アカウントについては、trans の「元の」レコードとのみ比較できます。

> trans <- data.frame(
+     ACCOUNT_NUM = c(1,2,3,3,3,6,7,4,4,10),
+     TRAN_DATE = as.Date(c("2008-02-02", "2008-04-02",
+                           "2008-03-16", "2009-08-22",
+                           "2008-05-05", "2010-11-03",
+                           "2008-09-18", "2009-10-14",
+                           "2009-01-15", "2011-07-06")),
+     BALANCE = c("orig", "orig", "orig", "orig", "revised", "orig", "revised", "revised", "revised", "orig"))

次のように、この状況に合わせてコードを実装しようとしました。

library(plyr)
adply(accts, 1, transform,
            TRAN_DATE = { 
                 if(STATUS == "old")
                 {
                    data <- subset(trans, ACCOUNT_NUM == ACCOUNT &
                                             TRAN_DATE < DATE & BALANCE == "orig")
                 }else{
                    data <- subset(trans, ACCOUNT_NUM == ACCOUNT &
                                             TRAN_DATE < DATE & BALANCE == "revised")
                 }
                 tail(data$TRAN_DATE, 1) })

このコードから次のエラーが発生します。

Error in data.frame(list(ACCOUNT = 1L, DATE = 13939, STATUS = 1L), BALANCE = list( : 
  arguments imply differing number of rows: 1, 0

最初の投稿でこの要件を指定しなかったことをお詫びします。問題が発生することを認識していませんでした。

4

1 に答える 1