我具有根据用户选择对可变数据帧列表执行操作的功能。该函数主要执行通用操作,但有一些特定于数据帧的操作。
如果选择了所有数据框,我的代码运行正常,但是如果未选择所有数据框,我无法使其正常工作。
以下内容提供了一个最小的可重现示例:
# User switches.
df1Switch <- TRUE
df2Switch <- TRUE
df3Switch <- TRUE
# DF creation.
set.seed(1)
df <- data.frame(X=sample(1:10), Y=sample(11:20))
if (df1Switch) df1 <- df
if (df2Switch) df2 <- df
if (df3Switch) df3 <- df
# Function to do something.
fn_something <- function(file_list, file_names) {
df <- file_list
# Do lots of generic things.
df$Z <- df$X + df$Y
# Do a few specific things.
if (file_names == "Name1") df$X <- df$X + 1
else if (file_names == "Name2") df$X <- df$Z - 1
else if (file_names == "Name3") df$Y <- df$X + df$Y
return(df)
}
# Call function to do something.
file_list <- list(Name1=df1, Name2=df2, Name3=df3)
file_names <- names(file_list)
all_df <- do.call(rbind,mapply(fn_something, file_list, file_names,
SIMPLIFY=FALSE))
在这种情况下,由于用户选择创建所有三个数据框,因此代码运行良好。我使用命名列表,以便可以针对正确的数据帧执行特定操作。
输出看起来像这样(实际数字并不重要):
X Y Z
Name1.1 4 13 16
Name1.2 5 12 16
Name1.3 6 16 21
: : : :
Name2.1 15 13 16
: : : :
如果用户选择不创建某些数据框,则会出现问题,例如:
# User switches.
df1Switch <- TRUE
df2Switch <- FALSE
df3Switch <- TRUE
不足为奇,在这种情况下,未找到对象会导致错误:
> # Call function to do something.
> file_list <- list(Name1=df1, Name2=df2, Name3=df3)
Error: object 'df2' not found
我想做的是根据此伪代码的行有条件地指定file_list
的内容:
file_list <- list(if (df1Switch) {Name1=df1}, if (df2Switch) {Name2=df2}, if (df3Switch) {Name3=df3})
我遇到了list.foldLeft
Conditionally merge list elements,但我不知道这是否合适。
答案 0 :(得分:1)
(我将重新发表我的评论:)
通常,我鼓励您考虑使用数据帧列表而不是单个帧。我的理由:
list_of_frames <- lapply(list_of_frames, some_func)
比做类似的事情容易得多:
for (nm in c("df1", "df2", "df3")) {
d <- get(nm)
d <- some_func(d)
assign(nm, d)
}
尤其是在处理非全局环境时(即在函数中执行此操作)。
需要明确的是,“轻松”是主观的:尽管它确实赢得了代码高尔夫,但我发现阅读和理解”我正在{{1的每个元素上运行some_func
}},然后保存结果。。 (您甚至可以将其保存到新的帧列表中,从而保持原始帧不变。)
您也可以有条件地做事,例如
list_of_frames
话虽如此...直接回答您的一艘班轮:
needs_work <- sapply(list_of_frames, some_checker_func) # returns logical
# or
needs_work <- c("df1", "df2") # names of elements of list_of_frames
list_of_frames[needs_work] <- lapply(list_of_frames[needs_work], some_func)
这利用了未声明的c(if (df1Switch) list(Name1=df1), if (df2Switch) list(Name2=df2), if (df3Switch) list(Name3=df3))
导致else
和NULL
的{{1}}压缩(丢弃)特性这一事实。您可以通过以下方式查看它的运行情况:
NULL