3

私はこれを持っていますdata.frame

  id  |  amount1  | amount2  |  day1  |  day2
 ---------------------------------------------
  A   |    10     |    32    |   0    |   34
  B   |    54     |    44    |   8    |   43
  C   |    45     |    66    |   16   |   99    

df <- data.frame(id=c('A','B','C'), amount1=c(10,54,45), amount2=c(32,44,66),  day1=c(0,8,16), day2=c(34,43,99))

apply機能したい

df$res <-  apply(df, 1, myfunc)

どこ

myfunc <- function(x,y) sum(x) * mean(y)

関数の引数として列変数を渡したいので、基本的に次のようになります。

 apply(df, 1, myfunc, c(amount1, amount2), c(day1, day2))

最初の行の場合、これは

myfunc(c(10,32),c(0,34))
# [1] 714

これはできますか?

4

3 に答える 3

4

data.table解決策。

require(data.table)
dt <- data.table(df) # don't depend on `id` column as it may not be unique
# instead use 1:nrow(dt) in `by` argument
dt[, res := myfunc(c(amount1,amount2), c(day1, day2)), by=1:nrow(dt)]
> dt
#    id amount1 amount2 day1 day2    res
# 1:  A      10      32    0   34  714.0
# 2:  B      54      44    8   43 2499.0
# 3:  C      45      66   16   99 6382.5

of を取り、 ofおよびで乗算しdaysたい列がたくさんある場合は、 を使用せずにこの方法で行います。ただし、本当に関数が必要な場合は、簡単に実装できます。meansumamount1amount2myfunc

# dummy example
set.seed(45)
df <- data.frame(matrix(sample(1:100, 200, replace=T), ncol=10))
names(df) <- c(paste0("amount", 1:2), paste0("day", 1:8))
df$idx <- 1:nrow(df) # idx column for uniqueness

# create a data.table
require(data.table)
calc_res <- function(df) {
    dt <- data.table(df)
    # first get the mean
    id1 <- setdiff(names(dt), grep("day", names(dt), value=TRUE))
    dt[, res := rowMeans(.SD), by=id1]
    # now product of sum(amounts) and current res
    id2 <- setdiff(names(dt), names(dt)[1:2])
    dt[, res := sum(.SD) * res, by=id2]
}
dt.fin <- calc_res(df)
于 2013-01-21T15:36:08.987 に答える
3

このような:

df$res <- apply(df, 1, function(x) myfunc(as.numeric(x[c("amount1", "amount2")]),
                                          as.numeric(x[c("day1", "day2")])))

plyr::adplyしかし、代替案として検討してください:

library(plyr)
adply(df, 1, transform, res = myfunc(c(amount1, amount2), c(day1, day2)))
#   id amount1 amount2 day1 day2    res
# 1  A      10      32    0   34  714.0
# 2  B      54      44    8   43 2499.0
# 3  C      45      66   16   99 6382.5
于 2013-01-21T15:23:47.697 に答える
1

これはあなたの例で機能します。おそらく、同じ手法を実際の問題に使用できます。

> apply(df[-1], 1, function(x) myfunc(x[1:2], x[3:4]))
## [1]  714.0 2499.0 6382.5

flodel が示すように、サブセット操作の 1 つに名前を使用して、これらの列のみが適用に使用されるようにするのが最善です。渡されたベクトルが文字に変換されるのを防ぐには、サブセットが必要ですapply。列を明示的に指定すると、データ フレームに列を追加しても、この問題は発生しません。

apply(df[c("amount1", "amount2", "day1", "day2")], 1, 
      function(x) myfunc(x[1:2], x[3:4])
     )

実際には、次のようなコードを作成する可能性が高くなります。

amount <- c("amount1", "amount2")
day    <- c("day1", "day2")

df$res <- apply(df[c(amount, day)], 1, function(x) myfunc(x[amount], x[day]))
于 2013-01-21T15:13:16.993 に答える