1

私は R に大きなデータフレームを持っています。これはすべて次のようになります。

    name   amount   date1       date2  days_out year
    JEAN  318.5 1971-02-16 1972-11-27  650 days 1971
 GREGORY 1518.5       <NA>       <NA>   NA days 1971
    JOHN  318.5       <NA>       <NA>   NA days 1971
  EDWARD  318.5       <NA>       <NA>   NA days 1971
  WALTER  518.5 1971-07-06 1975-03-14 1347 days 1971
   BARRY 1518.5 1971-11-09 1972-02-09   92 days 1971
   LARRY  518.5 1971-09-08 1972-02-09  154 days 1971
   HARRY  318.5 1971-09-16 1972-02-09  146 days 1971
   GARRY 1018.5 1971-10-26 1972-02-09  106 days 1971

days_out が 60 未満の場合、90% の割引が適用されます。60-90、70% 割引。毎年のすべての金額の割引合計を調べる必要があります。私の非常に恥ずかしい回避策は、関連する年ごとに次のような R スクリプトを作成する Python スクリプトを作成することです。

tmp <- members[members$year==1971, ]
tmp90 <- tmp[tmp$days_out <= 60  & tmp$days_out > 0  & !is.na(tmp$days_out),  ]
tmp70 <- tmp[tmp$days_out <= 90  & tmp$days_out > 60 & !is.na(tmp$days_out),  ]
tmp50 <- tmp[tmp$days_out <= 120 & tmp$days_out > 90 & !is.na(tmp$days_out),  ]
tmp30 <- tmp[tmp$days_out <= 180 & tmp$days_out >120 & !is.na(tmp$days_out),  ]
tmp00 <- tmp[tmp$days_out > 180 | is.na(tmp$days_out), ]
details.1971 <- c(1971, nrow(tmp),
  nrow(tmp90), sum(tmp90$amount), sum(tmp90$amount) * .9,
    nrow(tmp70), sum(tmp70$amount), sum(tmp70$amount) * .7,
    nrow(tmp50), sum(tmp50$amount), sum(tmp50$amount) * .5,
    nrow(tmp30), sum(tmp30$amount), sum(tmp90$amount) * .9,
    nrow(tmp00), sum(tmp00$amount))
membership.for.chart <- rbind(membership.for.chart,details.1971)

それはうまく動作します。tmp フレームとベクトルは上書きされますが、問題ありません。しかし、私はここで R に関するエレガントで効率的なすべてを完全に打ち負かしたことを知っています。1 か月前に初めて R を立ち上げましたが、長い道のりを歩んできました。しかし、私はこれについてどうすればよかったのか本当に知りたいですか?

4

2 に答える 2

2

cut関数または関数のいずれかを使用できますfindInterval。正確なコードは、コンソール出力と明確に通信されないオブジェクトの内部に依存します。それdays_outが difftime-object である場合。次に、次のようなものが機能する可能性があります。

disc_amt <- with(tmp, amount*c(.9, .7, .5, .9, 1)[
                                 findInterval(days_out, c(0, 60, 90, 120, 180, Inf] )

dput()そのオブジェクトの出力を投稿するtmpか、おそらくdput(head(tmp, 20))それが本当に大きい場合は、テストを続行する必要があります。(実際の割引は、私が期待した方法で注文されたようには見えませんでした。)

于 2012-12-14T23:32:23.003 に答える
2

うわー、R スクリプトを生成する Python スクリプトを作成しましたか? 眉を上げて考えてみてください...

うまくいけば、これで始めることができます:

#Import your data; add dummy column to separate 'days' suffix into its own column
dat <- read.table(text = "   name   amount   date1       date2  days_out dummy year
    JEAN  318.5 1971-02-16 1972-11-27  650 days 1971
 GREGORY 1518.5       <NA>       <NA>   NA days 1971
    JOHN  318.5       <NA>       <NA>   NA days 1971
  EDWARD  318.5       <NA>       <NA>   NA days 1971
  WALTER  518.5 1971-07-06 1975-03-14 1347 days 1971
   BARRY 1518.5 1971-11-09 1972-02-09   92 days 1971
   LARRY  518.5 1971-09-08 1972-02-09  154 days 1971
   HARRY  318.5 1971-09-16 1972-02-09  146 days 1971
   GARRY 1018.5 1971-10-26 1972-02-09  106 days 1971",header = TRUE,sep = "")

#Repeat 3 times
df <- rbind(dat,dat,dat)

#Create new year variable
df$year <- rep(1971:1973,each = nrow(dat))

#Breaks for discount levels
ct <- c(0,60,90,120,180,Inf)

#Cut into a factor
df$fac <- cut(df$days_out,ct)

#Create discount amounts for each row
df$discount <- c(0.9,0.7,0.5,0.9,1)[df$fac]
df$discount[is.na(df$discount)] <- 1

#Calc adj amount
df$amount_adj <- with(df,amount * discount)

#I use plyr a lot, but there are many, many
# alternatives
library(plyr)
ddply(df,.(year),summarise,
            amt = sum(amount_adj),
            total = length(year),
            d60 = length(which(fac == "(0,60]")))

ddply最後のコマンドで集計値をいくつか計算しただけです。自分で拡張できると思います。

于 2012-12-14T23:36:44.407 に答える