将for循环转换为apply / lapply / sapply:基于列的操作

时间:2017-05-18 05:49:41

标签: r for-loop vectorization

假设我有以下for loop代码,这完全有效:

for (i in 1:nrow(Dir)) {
    if (is.na(Dir[i, 3]) == TRUE) {
        Dir[i, 3] = Dir[i, 5]/Dir[i, 4]
    }
}

它的作用是检查每一行的列元素,如果有NA,它会将NA替换为将5th column元素除以{{{ 1}}元素。

如何将基于列元素的此类和4th column循环转换为使用for的代码?

了解有关apply/lapply/sapply的更多信息的任何综合资源也将受到赞赏。谢谢。

1 个答案:

答案 0 :(得分:3)

如果你真的想在这里使用apply,你可以这样做:

n_rows = 20
Dir = data.frame(
    a = sample(1:100, n_rows),
    b = sample(1:100, n_rows),
    c = sample(c(NA, 1, 2), n_rows, replace = TRUE),
    d = sample(1:100, n_rows),
    e = sample(1:100, n_rows)
)

# MARGIN = 1: apply along the rows (MARGIN = 2 for columns)
Dir$c = apply(Dir, MARGIN = 1, FUN = function(row) {
    if (is.na(row[3])) {
        return(row[5] / row[4])
    } else {
        return(row[3])
    }
})

但是: apply不一定比for循环更快或更有效。矢量化代码,如baptiste的建议

Dir[ , 3] = ifelse(is.na(Dir[ , 3]), Dir[, 5]/Dir[, 4], Dir[ , 3])
一旦你的数据大到足以让差异变得重要,

通常比两者都要快,并且一旦你了解了它的工作原理,就需要减少打字的工作量。