I have the following function:
fxn1 <- function (var1, ..., data) {
if (!missing(data)) {
var1 <- data[[deparse(substitute(var1))]]
}
data.frame(var1, ...)
}
Tree_Data <- data.frame(Tree_Number = as.factor(1:12), Diameter = rnorm(12, 10, 2), Height = rnorm(12, 60, 12))
fxn1(Tree_Number, Tree_Data$Diameter, Tree_Data$Height, data = Tree_Data)
This function has been simplified to illustrate my point.
I want to have two input arguments (var1
and ...
) that can be provided as either standalone vectors or columns from a data frame. The ...
argument can be one or more vectors or columns, as long as they're the same length as the vector provided for the var1
argument.
How can I write this function such that the data
argument can supply columns for both the var1
and ...
arguments?
Furthermore, I wish to have the output of this function report the column names from the original data frame (Tree_Number
, Diameter
, and Height
). As it stands, the column names being reported by the function are var1
, Tree_Data.Diameter
, and Tree_Data.Height
.
CodePudding user response:
I'm not sure about your purpose, but if you mean to use function fxn1
as fxn1(Tree_Number, Diameter, Height, data = Tree_Data)
, you may try
fxn1 <- function (var1, ..., data) {
if (!missing(data)) {
var1 <- data[[deparse(substitute(var1))]]
}
x <- sapply(substitute((...)), deparse)[-1]
data.frame(var1, data[x])
}
fxn1(Tree_Number, Diameter, Height, data = Tree_Data)
var1 Diameter Height
1 1 11.178169 58.33416
2 2 11.338480 45.01997
3 3 12.524902 30.98330
4 4 6.232644 58.07779
5 5 10.611835 54.18964
6 6 7.009949 55.67097
7 7 9.709637 46.79252
8 8 11.454289 65.89518
9 9 5.845062 63.50421
10 10 8.991004 62.18654
11 11 11.981330 55.69941
12 12 8.488162 57.20142
fxn2 <- function (..., data) {
x <- sapply(substitute((...)), deparse)[-1]
data.frame(data[x])
}
fxn2(Tree_Number, Diameter, Height, data = Tree_Data)
Tree_Number Diameter Height
1 1 11.178169 58.33416
2 2 11.338480 45.01997
3 3 12.524902 30.98330
4 4 6.232644 58.07779
5 5 10.611835 54.18964
6 6 7.009949 55.67097
7 7 9.709637 46.79252
8 8 11.454289 65.89518
9 9 5.845062 63.50421
10 10 8.991004 62.18654
11 11 11.981330 55.69941
12 12 8.488162 57.20142
Or simply remove []
in if
statement will work.
fxn3 <- function (var1, ..., data) {
if (!missing(data)) {
var1 <- data[deparse(substitute(var1))]
}
x <- sapply(substitute((...)), deparse)[-1]
data.frame(var1, data[x])
}
CodePudding user response:
fxn1 <- function (var1, ..., data) {
nms <- as.character(substitute(...()))
nm1 <- deparse(substitute(var1))
if (missing(data))
setNames(data.frame(c(list(var1), list(...))),
sub('.*\\$', '', c(nm1, nms)))
else data[c(nm1, nms)]
}
Tree_Data <- data.frame(Tree_Number = as.factor(1:12),
Diameter = rnorm(12, 10, 2), Height = rnorm(12, 60, 12))
fxn1(Tree_Data$Tree_Number, Tree_Data$Diameter, Tree_Data$Height)
Tree_Number Diameter Height
1 1 12.692108 73.77180
2 2 9.278630 48.24943
3 3 7.436189 43.20851
4 4 8.961796 64.04443
5 5 12.191659 48.76907
6 6 10.938422 46.87867
7 7 13.732354 66.54974
8 8 9.245929 47.98816
9 9 5.443331 78.79621
10 10 9.633676 69.40670
11 11 9.466689 57.41067
12 12 9.221958 87.18004
fxn1(Tree_Number, Diameter, Height, data = Tree_Data)
Tree_Number Diameter Height
1 1 12.692108 73.77180
2 2 9.278630 48.24943
3 3 7.436189 43.20851
4 4 8.961796 64.04443
5 5 12.191659 48.76907
6 6 10.938422 46.87867
7 7 13.732354 66.54974
8 8 9.245929 47.98816
9 9 5.443331 78.79621
10 10 9.633676 69.40670
11 11 9.466689 57.41067
12 12 9.221958 87.18004