これは典型的なplyr
問題のように思われるかもしれませんが、私は別のことを考えています。これが私が最適化したい関数です(for
ループをスキップします)。
# dummy data
set.seed(1985)
lst <- list(a=1:10, b=11:15, c=16:20)
m <- matrix(round(runif(200, 1, 7)), 10)
m <- as.data.frame(m)
dfsub <- function(dt, lst, fun) {
# check whether dt is `data.frame`
stopifnot (is.data.frame(dt))
# check if vectors in lst are "whole" / integer
# vector elements should be column indexes
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol
# fall if any non-integers in list
idx <- rapply(lst, is.wholenumber)
stopifnot(idx)
# check for list length
stopifnot(ncol(dt) == length(idx))
# subset the data
subs <- list()
for (i in 1:length(lst)) {
# apply function on each part, by row
subs[[i]] <- apply(dt[ , lst[[i]]], 1, fun)
}
# preserve names
names(subs) <- names(lst)
# convert to data.frame
subs <- as.data.frame(subs)
# guess what =)
return(subs)
}
そして今、短いデモンストレーション...実際、私は主に何をしようとしていたのかを説明しようとしています。オブジェクトdata.frame
に集められたベクトルでサブセット化したかった。list
これは心理学研究におけるデータ操作に伴う関数のコードの一部であるためm
、性格調査票(10科目、20変数)の結果とみなすことができます。リスト内のベクトルは、質問票のサブスケール(性格特性など)を定義する列インデックスを保持します。各サブスケールは、いくつかの項目(の列data.frame
)によって定義されます。各サブスケールのスコアsum
が行の値(各サブジェクトのアンケートのその部分の結果)の(または他の関数)にすぎないと仮定すると、次のように実行できます。
> dfsub(m, lst, sum)
a b c
1 46 20 24
2 41 24 21
3 41 13 12
4 37 14 18
5 57 18 25
6 27 18 18
7 28 17 20
8 31 18 23
9 38 14 15
10 41 14 22
私はこの関数を一瞥しましたが、この小さなループがコードをまったく損なうものではないことを認めなければなりません...しかし、これを行うためのより簡単で効率的な方法がある場合は、私に知らせてください!