Как использовать аргументы в вызове функции в качестве имен в фреймах данных в R? - PullRequest
1 голос
/ 27 мая 2020

Я пытаюсь изменить вывод tapply, чтобы получить вертикальное транспонирование результатов.

Примерно так:

Levels of y  Mean of x

A              1.7

B              3.5

C              5.0

вместо:

A     B    C

1.7  3.5  5.0 

Мне удалось создать фрейм данных:

myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
print(a)
}

attach(InsectSprays)

myfunction(count,spray,mean)

Это работает и дает следующее:

  names.array1.    array1
1             A 14.500000
2             B 15.333333
3             C  2.083333
4             D  4.916667
5             E  3.500000
6             F 16.666667

Проблема 1)

Теперь я хотел бы измените функцию, чтобы изменить имена столбцов фрейма данных, используя аргументы, которые передаются моей функции при вызове самой функции (в данном случае c case "spray" и "Sum of count").

Я пробовал что-то вроде этого

myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
colnames(a)<-c(y,print(FUN,"of",x)
print(a)
}

, но мне кажется, R пытается использовать весь вектор y вместо своего имени.

Я не могу понять, какое решение может быть.

Я также безуспешно пробовал использовать args () и formals ().

Проблема 2)

Я хотел бы вызвать myfunction таким образом, передав data = ... применить к исходному вызову (чтобы избежать присоединения и отсоединения набора данных или передачи переменной s в виде df $ variable1). Я пробовал:

myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
print(a)
}

myfunction<-(count,spray,sum,data=InsectSprays)

, но tapply не находит объект «спрей».

Очевидно, решение всех моих проблем могло заключаться в использовании aggregate (), но я думаю, что решения эти вопросы научат меня многому в написании функций. Большое спасибо за вашу помощь.

1 Ответ

2 голосов
/ 27 мая 2020

Метод, который вы пытаетесь использовать, называется нестандартная оценка , и он широко используется в семействе пакетов tidyverse, а также в некоторых функциях в базе R, таких как with , within и оператор $.

Вы можете использовать sh, чтобы изучить концепцию здесь .

Тем временем также можно использовать функцию в базе R, которая использует нестандартные оценка с использованием deparse и substitute:

myfunction <- function(x, y, data, FUN, ...) 
{
  x <- deparse(substitute(x))
  y <- deparse(substitute(y))
  array1 <- tapply(data[[x]], data[[y]], FUN, ...)
  a <- setNames(data.frame(names(array1),array1), 
               c(y, paste(deparse(substitute(FUN)), "of", y)))
  rownames(a) <- NULL
  print(a)
}

myfunction(count, spray, data = InsectSprays, mean)
#>   spray mean of spray
#> 1     A     14.500000
#> 2     B     15.333333
#> 3     C      2.083333
#> 4     D      4.916667
#> 5     E      3.500000
#> 6     F     16.666667

myfunction(cyl, gear, mtcars, sum)
#>   gear sum of gear
#> 1    3         112
#> 2    4          56
#> 3    5          30

Более продвинутая версия этой функции также позволит вам передавать векторы напрямую без аргумента data:

myfunction <- function(x, y, data, FUN, ...) 
{
  if (missing(data)) data <- parent.frame()
  y_name   <- deparse(substitute(y))
  col_name <- paste(deparse(substitute(FUN)), "of", y_name)
  x        <- eval(substitute(x), envir = as.environment(data))
  y        <- eval(substitute(y), envir = as.environment(data))

  array1 <- tapply(x, y, FUN, ...)
  a      <- setNames(data.frame(names(array1), array1), c(y_name, col_name))
  rownames(a) <- NULL
  print(a)
}

Он имеет те же функциональные возможности, что и первый пример, но, кроме того, вы можете запускать его с использованием векторов в вызывающей среде:

var1 <- 1:10
var2 <- rep(1:2, 5)

myfunction(var1, var2, FUN = median)
#>   var2 median of var2
#> 1    1              5
#> 2    2              6

Создано 27 мая 2020 года пакет REPEX (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...