我想将函数应用于数据框的每一行,如下所示。我知道如何在数据框只包含数字的情况下使用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], ... )
更清洁的方法。有什么想法吗?
提前致谢!
答案 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"