更好的方法是将这个函数应用到数据帧的每一行?

时间:2011-11-08 21:09:16

标签: r

我想将函数应用于数据框的每一行,如下所示。我知道如何在数据框只包含数字的情况下使用apply,但是如果行包含booleans / logicals,字符串和整数呢?例如:

df <- data.frame(x=1:10,
                 y=c(TRUE, FALSE),
                 z=letters[1:10],
                 stringsAsFactors=FALSE)

RowFunction <- function(row) {
  if (row$y) return(row$x)
  return (row$z)
}

sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) })

有更好的方法吗?我的第一个想法是在将apply(df, 1, RowFunction)添加到RowFunction的开头之后使用row <- as.list(row),但这不起作用,因为应用将df强制转换为数组,该数组无法处理包含不同数据类型的行。 / p>

仅仅为了我的R知识,我想知道是否有比sapply(1:dim(df)[1], ... )更清洁的方法。有什么想法吗?

提前致谢!

2 个答案:

答案 0 :(得分:6)

在这种情况下,您只需使用ifelse

即可
sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) })
 [1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j"

with(df, ifelse(y, x, z))
 [1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j"

为了方便和可读性,我还使用了with - 这样您就可以按名称引用列,而无需使用$运算符。

答案 1 :(得分:0)

ifelse功能可以使用lapply执行此操作:

 lapply(df$y, ifelse, df$x, df$z)  # does return list with varying modes

我之前的(更笨重)版本:

 res <- list()
 for(i in seq_along(rownames(df) ) ) { res <- c(res, df[i,1+2*!df[i,"y"] ]) }
 res
#--------
[[1]]
[1] 1

[[2]]
[1] "b"

[[3]]
[1] 3

[[4]]
[1] "d"

[[5]]
[1] 5

[[6]]
[1] "f"

[[7]]
[1] 7

[[8]]
[1] "h"

[[9]]
[1] 9

[[10]]
[1] "j"