表示函数中的中间处理步骤的适当符号是什么?
What's the appropriate notation for representing intermediate processing steps in a function?
假设我定义了以下函数来读取一组文件:
read_File <- function(file){
# read Excel file
df1 <- read.xls(file,sheet=1, pattern="Name", header=T, na.strings=("##"), stringsAsFactors=F)
# remove rows where Name is empty
df2 <- df1[-which(df1$Name==""),]
# remove rows where "Name" is repeated
df3 <- df2[-which(df2$Name=="Name"),]
# remove all empty columns (anything with an auto-generated colname)
df4 <- df3[, -grep("X\.{0,1}\d*$", colnames(df3))]
row.names(df4) <- NULL
df4$FileName <- file
return(df4)
}
它像这样工作得很好,但是定义 df1...df4
来表示中间步骤感觉不太好。有没有更好的方法在不影响可读性的情况下做到这一点?
我认为没有理由单独保存中间对象,除非它们需要多次使用。这不是你的代码中的情况,所以我会用 df
:
替换你所有的 df[0-9]
read_File <- function(file){
# read Excel file
df <- read.xls(file,sheet = 1, pattern = "Name", header = T,
na.strings = ("##"), stringsAsFactors = F)
# remove rows where Name is empty
df <- df[-which(df$Name == ""), ]
# remove rows where "Name" is repeated
df <- df[-which(df$Name == "Name"), ]
# remove all empty columns (anything with an auto-generated colname)
df <- df[, -grep("X\.{0,1}\d*$", colnames(df))]
row.names(df) <- NULL
df$FileName <- file
return(df)
}
df3
不是一个很好的描述性变量名称 - 它不会告诉您有关变量的更多信息 df
。像这样按顺序命名变量步骤也会造成维护负担:如果您需要在中间添加一个新步骤,您将需要重命名所有后续对象以保持一致性——这听起来既烦人又存在潜在的错误风险。
(或者有一些像 df2.5
这样的 hacky,它很丑并且不能很好地概括。)一般来说,我认为 sequentially named variables are almost always bad practice, even when they are separate objects that you need saved.
此外,保留中间对象也不是很好的内存使用方式。在大多数情况下这无关紧要,但如果您的数据很大,那么单独保存所有中间步骤将大大增加处理过程中使用的内存量。
评论非常好,非常详细 - 它们告诉您所有您需要了解的代码中发生的事情。
如果是我,我可能会结合一些步骤,像这样:
read_File <- function(file){
# read Excel file
df <- read.xls(file,sheet = 1, pattern = "Name", header = T,
na.strings = ("##"), stringsAsFactors = F)
# remove rows where Name is bad:
bad_names <- c("", "Name")
df <- df[-which(df$Name %in% bad_names), ]
# remove all empty columns (anything with an auto-generated colname)
df <- df[, -grep("X\.{0,1}\d*$", colnames(df))]
row.names(df) <- NULL
df$FileName <- file
return(df)
}
省略一个 bad_names
向量可以节省一行并且更具参数性 - 将 bad_names
提升为函数参数(可能使用默认值 c("", "Name")
)将是微不足道的以便用户可以自定义它。
假设我定义了以下函数来读取一组文件:
read_File <- function(file){
# read Excel file
df1 <- read.xls(file,sheet=1, pattern="Name", header=T, na.strings=("##"), stringsAsFactors=F)
# remove rows where Name is empty
df2 <- df1[-which(df1$Name==""),]
# remove rows where "Name" is repeated
df3 <- df2[-which(df2$Name=="Name"),]
# remove all empty columns (anything with an auto-generated colname)
df4 <- df3[, -grep("X\.{0,1}\d*$", colnames(df3))]
row.names(df4) <- NULL
df4$FileName <- file
return(df4)
}
它像这样工作得很好,但是定义 df1...df4
来表示中间步骤感觉不太好。有没有更好的方法在不影响可读性的情况下做到这一点?
我认为没有理由单独保存中间对象,除非它们需要多次使用。这不是你的代码中的情况,所以我会用 df
:
df[0-9]
read_File <- function(file){
# read Excel file
df <- read.xls(file,sheet = 1, pattern = "Name", header = T,
na.strings = ("##"), stringsAsFactors = F)
# remove rows where Name is empty
df <- df[-which(df$Name == ""), ]
# remove rows where "Name" is repeated
df <- df[-which(df$Name == "Name"), ]
# remove all empty columns (anything with an auto-generated colname)
df <- df[, -grep("X\.{0,1}\d*$", colnames(df))]
row.names(df) <- NULL
df$FileName <- file
return(df)
}
df3
不是一个很好的描述性变量名称 - 它不会告诉您有关变量的更多信息 df
。像这样按顺序命名变量步骤也会造成维护负担:如果您需要在中间添加一个新步骤,您将需要重命名所有后续对象以保持一致性——这听起来既烦人又存在潜在的错误风险。
(或者有一些像 df2.5
这样的 hacky,它很丑并且不能很好地概括。)一般来说,我认为 sequentially named variables are almost always bad practice, even when they are separate objects that you need saved.
此外,保留中间对象也不是很好的内存使用方式。在大多数情况下这无关紧要,但如果您的数据很大,那么单独保存所有中间步骤将大大增加处理过程中使用的内存量。
评论非常好,非常详细 - 它们告诉您所有您需要了解的代码中发生的事情。
如果是我,我可能会结合一些步骤,像这样:
read_File <- function(file){
# read Excel file
df <- read.xls(file,sheet = 1, pattern = "Name", header = T,
na.strings = ("##"), stringsAsFactors = F)
# remove rows where Name is bad:
bad_names <- c("", "Name")
df <- df[-which(df$Name %in% bad_names), ]
# remove all empty columns (anything with an auto-generated colname)
df <- df[, -grep("X\.{0,1}\d*$", colnames(df))]
row.names(df) <- NULL
df$FileName <- file
return(df)
}
省略一个 bad_names
向量可以节省一行并且更具参数性 - 将 bad_names
提升为函数参数(可能使用默认值 c("", "Name")
)将是微不足道的以便用户可以自定义它。