apply() 関数を使用して、複雑な for ループを置き換えたいと考えています。
最初に理解したいのは、最初の列にのみ適用したい場合に、100 列のマトリックスで apply() を使用する方法です。これは可能ですか?
例えば:
for (i in 1:100){ if (runif(1,0,1)<0.01) { a[i,1]<-3-b[i,1] } }
これをどのように翻訳して適用できますか?
apply() 関数を使用して、複雑な for ループを置き換えたいと考えています。
最初に理解したいのは、最初の列にのみ適用したい場合に、100 列のマトリックスで apply() を使用する方法です。これは可能ですか?
例えば:
for (i in 1:100){ if (runif(1,0,1)<0.01) { a[i,1]<-3-b[i,1] } }
これをどのように翻訳して適用できますか?
1.apply
は行列または配列で使用するように設計されていますが、1 つの特定の列はベクトルであり、代わりにorapply
を使用する方が賢明なファミリ関数を考慮しています。mapply
sapply
# By passing b[, 1]. Two options
v <- sapply(b[, 1], function(x) if(runif(1, 0 ,1) < 0.01) 3 - x else NA)
v <- sapply(b[, 1], function(x) ifelse(runif(1, 0 ,1) < 0.01, 3 - x, NA))
a[!is.na(v), 1] <- v[!is.na(v)]
# By going through indices
a[, 1] <- sapply(1:nrow(b), function(x)
if(runif(1, 0, 1) < 0.01) 3 - b[x, 1] else a[x, 1])
# Using mapply to avoid problems related to NAs
mapply(function(x, y) ifelse(runif(1, 0, 1) < 0.01, 3 - y, x), a[, 1], b[, 1])
ただし、apply
Roman Luštrik が指摘したように、 then を使用することを主張する場合は、行列として見えるようにする必要があります。つまり、 を使用して次元を「削除」しないでdrop = FALSE
ください。
a[, 1] <- apply(b[, 1, drop = FALSE], 1, function(x)
if(runif(1, 0, 1) < 0.01) 3 - x else NA)
# This returns NAs to make it simpler for now
2.フローデルが指摘したように、可能な限りベクトル化を使用する必要があります。あなたの例では、一度に数値をrunif
生成できnrow(b)
、のベクトル化されたバージョンがあるため、これは可能if
です。ifelse
a[, 1] <- ifelse(runif(nrow(b), 0, 1) < 0.01, 3 - b[, 1], a[, 1])
そして、なしの最終的なアプローチif
はifelse
、
idx <- runif(100, 0, 1) < 0.01
a[idx, 1] <- 3 - b[idx, 1]
もちろん、必要なのは 1 つの列だけを渡すことだけです。
set.seed(357)
my.data <- data.frame(x = runif(10), y = runif(10), z = runif(10))
apply(my.data[, 1, drop = FALSE], MARGIN = 2, FUN = mean)
x
0.5234919