将函数应用于data.frame的每一列并组织输出

问题描述 投票:1回答:1

我有这个向量:

 x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)

我用这个函数:

myfunction <- function(x){
     n <- length(x)
     fx <- numeric(n)
     fx[1] <- min(x[1],0)
     for(i in 2:n){fx[i] <- min(0,fx[i-1]+x[i])}
     fx

     x_min <-min(x)
     fx_min <- min(fx)

     fx_05 <- numeric(n)
     fx_05[1] <- min(fx[1],0)
     for (i in 2:n) {
       if (sum(fx_05[i-1]+x[i])>0) {  
          fx_05[i] <- 0
       } else if ((sum(fx_05[i-1]+x[i]))<(fx_min*0.5)) {
          fx_05[i] <- (fx_min*0.5)
       } else { fx_05[i] <- sum(fx_05[i-1]+x[i]) }
     }
     fx_05
     as.data.frame(matrix(c(x, fx_05), ncol = 2 ))
}
xx <- myfunction(x)

数据框xx

    V1   V2
1    5  0.0
2    2  0.0
3   -4 -4.0
4   -6 -8.5
5   -2 -8.s
6    1 -7.5
7    4 -3.5
8    2 -1.5
9   -3 -4.5
10  -6 -8.5
11  -1 -8.5
12   8 -0.5
13   9  0.0
14   5  0.0
15  -6 -6.0
16 -11 -8.5`

我想将此函数应用于data.frame:

df <- data.frame(x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                   y <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                   z <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11))

使用:

output <- myfunction(df) 

它不起作用,并使用:

outputs <- data.frame(sapply(df, myfunction))

data.frame输出的形式不正确。对于data.frame的每个原始列,它应该是2列。

r function dataframe apply sapply
1个回答
2
投票

在这种情况下,您想使用lapply。它将处理data.frame的每一列,因为它实际上是等长向量的列表,并返回每列两列data.frame。

x <- lapply(df, myfunction)

此外,sapply工作得很好。唯一的区别是它在开始时看起来不同。请参阅print(x)了解所有解决方案之间的区别。

x <- sapply(df, myfunction)

之后,您可能希望再次将它们从列表组合到data.frame。你可以用do.call做到这一点

df2 <- do.call(cbind, x)

这会搞乱列名。你可以使用names更改这些

names(df2) <- NULL
df2
# 1    5  0.0   5  0.0   5  0.0
# 2    2  0.0   2  0.0   2  0.0
# 3   -4 -4.0  -4 -4.0  -4 -4.0
# 4   -6 -8.5  -6 -8.5  -6 -8.5
# ....

Side Note:

如果你没有data.frame但是有一个矩阵作为输入,另一个选项是带有applyMARGIN = 2

x <- apply(df, MARGIN = 2, myfunction)

虽然在这个例子中,它也可以工作,但是当你在向量中使用不同的数据类型时会遇到麻烦,因为它在应用函数之前将data.frame转换为矩阵。因此不建议这样做。有关这方面的更多信息,请访问this detailed and easy-to-understand post

进一步阅读: Hadley Wickham's Advanced R。另请参阅本网站上有关数据类型的部分。 Peter Werner's blog post


我非常感谢@Gregor在这篇文章中的意见。

© www.soinside.com 2019 - 2024. All rights reserved.