对 data.frame 的每一列应用一个函数并组织输出
Apply a function to each column of a data.frame and organize the output
我有这个向量:
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 列。
在这种情况下,您想使用 lapply
。它将处理 data.frame 的每一列,因为它实际上是一个等长向量的列表,并且 return 每个两列 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
# ....
旁注:
如果您没有 data.frame 而是矩阵作为输入,另一个选项是 apply
和 MARGIN = 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 对此 post 的投入。
我有这个向量:
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 列。
在这种情况下,您想使用 lapply
。它将处理 data.frame 的每一列,因为它实际上是一个等长向量的列表,并且 return 每个两列 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
# ....
旁注:
如果您没有 data.frame 而是矩阵作为输入,另一个选项是 apply
和 MARGIN = 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 对此 post 的投入。