[英]How to apply a function to dataframes within a list?
对于此数据:
list_data1 <- data.frame(date=c("Jan", "Feb", "Mar"), X0=c(3, 9, 5, 1, -2, 8),
X1=c(3, 9, 5, 1, -2, 8), mod=c("mod", "mod", "mod"))
list_data2 <- data.frame(date=c("Jan", "Feb", "Mar"), X0=c(3, 9, 5, 1, -2, 8),
X1=c(3, 9, 5, 1, -2, 8), mod=c("mod", "mod", "mod"))
merged.list <- list(list_data1, list_data2)
我需要将值 X0 和 X1 替换为X0 - mean(X0[1:3])
和X1 - mean(X1[1:3])
。
我还有其他列 X2、X3 等,所以我想在除 mod 和 date 之外的所有列上应用这些函数。
您可以使用lapply()
代码
lapply(merged.list, function(z){
# X0 - mean(X0[1:3])
z[, "X0"] <- z[, "X0"] - mean(z[, "X0"][1:3])
# X1 - mean(X1[1:3])
z[, "X1"] <- z[, "X1"] - mean(z[, "X1"][1:3])
# return df
z
})
# [[1]]
# date X0 X1 mod
# 1 Jan -2.6666667 -2.6666667 mod
# 2 Feb 3.3333333 3.3333333 mod
# 3 Mar -0.6666667 -0.6666667 mod
# 4 Jan -4.6666667 -4.6666667 mod
# 5 Feb -7.6666667 -7.6666667 mod
# 6 Mar 2.3333333 2.3333333 mod
# [[2]]
# date X0 X1 mod
# 1 Jan -2.6666667 -2.6666667 mod
# 2 Feb 3.3333333 3.3333333 mod
# 3 Mar -0.6666667 -0.6666667 mod
# 4 Jan -4.6666667 -4.6666667 mod
# 5 Feb -7.6666667 -7.6666667 mod
# 6 Mar 2.3333333 2.3333333 mod
更新
如果要将计算应用于data.frame()
中的所有数字列
lapply(merged.list, function(z){
# select all numeric columns
tmp1 <- z[, sapply(z, is.numeric)]
# do calcs
tmp2 <- sapply(tmp1, function(x){
x - mean(x[1:3])
})
# reassign to original data.frames
z[, sapply(z, is.numeric)] <- tmp2
# return
z
})
您可以在数字列上使用rapply
。
FUN <- function(x) x - mean(x[1:3])
r <- rapply(merged.list, f=FUN, classes="numeric", how="replace")
r
# [[1]]
# date X0 X1 mod
# 1 Jan -2.6666667 -2.6666667 mod
# 2 Feb 3.3333333 3.3333333 mod
# 3 Mar -0.6666667 -0.6666667 mod
# 4 Jan -4.6666667 -4.6666667 mod
# 5 Feb -7.6666667 -7.6666667 mod
# 6 Mar 2.3333333 2.3333333 mod
#
# [[2]]
# date X0 X1 mod
# 1 Jan -2.6666667 -2.6666667 mod
# 2 Feb 3.3333333 3.3333333 mod
# 3 Mar -0.6666667 -0.6666667 mod
# 4 Jan -4.6666667 -4.6666667 mod
# 5 Feb -7.6666667 -7.6666667 mod
# 6 Mar 2.3333333 2.3333333 mod
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.