如何应用将带有因子的data.frame返回到序列的函数?
示例:
s <- factor(c(10, 20, 30))
t <- factor(c("a", "b", "a"))
v <- c(5, 6, 4)
df <- data.frame(s,t,v)
所以data.frame df是这样的:
s t v
1 10 a 5
2 20 b 6
3 30 a 4
我还有一个返回data.frame的函数:
simpleFunc2 <- function(df, x){
tmp <- subset(df, df$s == x)
return(tmp)
}
现在我有一个序列
x <- c(20, 30, 10, 30, 10)
并希望结果auf将函数simpleFunc2应用于此序列。
我使用sapply
sapply(x, function(x) simpleFunc2(df, x))
但是我得到了
[,1] [,2] [,3] [,4] [,5]
s factor,1 factor,1 factor,1 factor,1 factor,1
t factor,1 factor,1 factor,1 factor,1 factor,1
v 6 4 5 4 5
如何获得正确的因子值?
此示例已简化。因此,在这种情况下,可能有更简单的方法。
答案 0 :(得分:17)
使用lapply
代替do.call
,如下所示:
do.call(rbind, lapply(x, function(x) simpleFunc2(df=df, x)))
答案 1 :(得分:5)
我看到你已经得到了问题的答案,但我认为你从该数据框中选择超集的方法过于复杂。 (如果该功能不具代表性,我表示道歉。我想提供一种比通过subset
更快的提取方法:
> df[ match(x, df$s), ]
s t v
2 20 b 6
3 30 a 4
1 10 a 5
3.1 30 a 4
1.1 10 a 5
# Save results as from:
> do.call(rbind, lapply(x, function(x) simpleFunc2(df, x)) )
s t v
2 20 b 6
3 30 a 4
31 10 a 5
32 30 a 4
5 10 a 5
答案 2 :(得分:0)
我不太明白这个问题,但两个答案都表明至少有一种简单方法一直缺失。键入
通常很方便merge(df,as.data.frame(x),by=1)
获取具有正确行/列名称的排序输出
s t v
1 10 a 5
2 10 a 5
3 20 b 6
4 30 a 4
5 30 a 4
就性能而言,所提出的方法不能与采用“匹配”的方法竞争,而是在接受的答案中容易地击败该方法。
microbenchmark::microbenchmark(
do.call=do.call(rbind, lapply(x, function(x) simpleFunc2(df, x))),
match=df[match(x, df$s), ],
merge= merge(df,as.data.frame(x),by=1))
Unit: microseconds
expr min lq median uq max neval
do.call 2487.451 2523.033 2547.4060 2604.3850 9554.748 100
match 175.117 180.197 183.2465 187.8135 248.835 100
merge 1020.307 1035.062 1049.4835 1071.6575 8057.059 100