我想用apply()函數替換複雜的for循環。在R中的矩陣的單列中使用apply()
我想弄清楚的第一件事是如何在100列的矩陣上使用apply(),當我只想將它應用到第一列時。這可能嗎?
例如:
for (i in 1:100){ if (runif(1,0,1)<0.01) { a[i,1]<-3-b[i,1] } }
如何翻譯這個申請?
我想用apply()函數替換複雜的for循環。在R中的矩陣的單列中使用apply()
我想弄清楚的第一件事是如何在100列的矩陣上使用apply(),當我只想將它應用到第一列時。這可能嗎?
例如:
for (i in 1:100){ if (runif(1,0,1)<0.01) { a[i,1]<-3-b[i,1] } }
如何翻譯這個申請?
因爲i
在餘處使用,apply
不是你的榜樣合適的工具。相反,你可以使用量化代碼:
a[, 1] <- if (runif(1,0,1) < 0.01) 3 - b[, 1] else a[, 1]
請注意,如果您想爲每行不同的隨機結果,那麼你需要畫nrow(a)
數量和使用矢量ifelse
:
a[, 1] <- ifelse(runif(nrow(a), 0, 1) < 0.01, 3 - b[, 1], a[, 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
1。 apply
設計用於矩陣或陣列,而一個特定的列是矢量,並考慮apply
家庭功能,而不是更明智地使用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
那麼,作爲羅馬Luštrik注意,你必須使它看起來像一個矩陣,即不通過使用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如flodel所述,只要有可能,您就必須嘗試使用矢量化。在您的例子,這是可能的,因爲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]
輸出'NA'是避免困難的一種方法。我認爲正確的'* apply'工具來複制OP後面的內容將是'mapply'。會給你的答案一個很好的補充。 – flodel