我有20个数据框,在每个数据框中,我想以相同的方式格式化同一列。当然,我可以制作list
dfs,然后使用lapply
。相反,我的目标是修改dfs,这样我最终不必将它们作为列表的元素访问,而是作为dfs。这是一个例子:
df1 <- data.frame(col1 = rnorm(5), col2 = rnorm(5))
df2 <- data.frame(col1 = rnorm(5), col2 = rnorm(5))
现在,假设我想在col1
和df1
中为df2
的每个值添加1。当然,我可以做到
df_list <- lapply(list(df1, df2), function(df) {
df$col1 <- df$col1 + 1
return(df)
})
但是现在df1
返回原始df而不是修改后的df。怎么做?
答案 0 :(得分:3)
基于OP代码的一个选项是在命名list2env
元素后使用list
names(df_list) <- paste0("df", 1:2)
list2env(df_list, envir = .GlobalEnv)
如果我们需要避免创建list
(建议拥有list
个数据集而不是在全局环境中创建单个对象),请使用assign
for
1}}循环
for(obj in paste0('df', 1:2)) {
assign(obj, `[<-`(get(obj), 'col1', value = get(obj)[['col1']] +1))
}
答案 1 :(得分:1)
你可以在这个问题中使用来自@ g-grothendieck的黑客:
并执行此操作:
list[df1, df2] <- lapply(list(df1, df2), function(df) {
df$col1 <- df$col1 + 1
return(df)
})
黑客
list <- structure(NA,class="result")
"[<-.result" <- function(x,...,value) {
args <- as.list(match.call())
args <- args[-c(1:2,length(args))]
length(value) <- length(args)
for(i in seq(along=args)) {
a <- args[[i]]
if(!missing(a)) eval.parent(substitute(a <- v,list(a=a,v=value[[i]])))
}
x
}
完整代码和结果
df1 <- data.frame(col1 = rnorm(5), col2 = rnorm(5))
# col1 col2
# 1 -0.5451934 0.5043287
# 2 -1.4047701 -0.1184588
# 3 0.1745109 0.8279085
# 4 -0.5066673 -0.3269411
# 5 0.4838625 -0.3895784
df2 <- data.frame(col1 = rnorm(5), col2 = rnorm(5))
# col1 col2
# 1 0.4168078 -0.44654445
# 2 -1.9991098 -0.06179699
# 3 -1.0625996 1.21098946
# 4 0.4977718 0.45834008
# 5 -1.6181048 0.97917877
list[df1, df2] <- lapply(list(df1, df2), function(df) {
df$col1 <- df$col1 + 1
return(df)
})
# > df1
# col1 col2
# 1 0.4548066 0.5043287
# 2 -0.4047701 -0.1184588
# 3 1.1745109 0.8279085
# 4 0.4933327 -0.3269411
# 5 1.4838625 -0.3895784
# > df2
# col1 col2
# 1 1.41680778 -0.44654445
# 2 -0.99910976 -0.06179699
# 3 -0.06259959 1.21098946
# 4 1.49777179 0.45834008
# 5 -0.61810483 0.97917877
答案 2 :(得分:1)
您可以使用如下循环来避免函数(及其临时环境):
df1 <- data.frame(col1 = 1:5, col2 = rnorm(5))
df2 <- data.frame(col1 = rep(0, 5), col2 = rnorm(5))
df1 # before
for (d in c("df1", "df2")) {
eval(parse(text = paste(d, "[['col1']] <- ", d, "[['col1']] + 1")))
}
df1 # after
选项2:
df1 <- data.frame(col1 = 1:5, col2 = rnorm(5))
df2 <- data.frame(col1 = rep(0, 5), col2 = rnorm(5))
df1 # before
df2 # before
eval(parse(text = unlist(lapply(c("df1", "df2"), function(x) {
expr.dummy <- quote(df$col1 <- df$col1 +1) # df will be replaced by df1, df2
gsub("df", x, deparse(expr.dummy))
}))))
df1 # after
df2 # after