Передача столбца DataFrame в качестве аргумента функции [duplicate]

Простым способом является добавление перед классом перед каждым селектором в файле css.

Я нахожу, что скрипт grunt может сделать это:

https: // github. ком / ericf / Грунт-CSS-селекторы

77
задан Bhargav Rao 15 March 2016 в 15:37
поделиться

3 ответа

Вы можете просто использовать имя столбца напрямую:

df <- data.frame(A=1:10, B=2:11, C=3:12)
fun1 <- function(x, column){
  max(x[,column])
}
fun1(df, "B")
fun1(df, c("B","A"))

Нет необходимости использовать substitute, eval и т. д.

Вы даже можете передать нужную функцию в качестве параметра :

fun1 <- function(x, column, fn) {
  fn(x[,column])
}
fun1(df, "B", max)

В качестве альтернативы, использование [[ также работает для выбора одного столбца за раз:

df <- data.frame(A=1:10, B=2:11, C=3:12)
fun1 <- function(x, column){
  max(x[[column]])
}
fun1(df, "B")
71
ответ дан joran 18 August 2018 в 06:43
поделиться
  • 1
    Есть ли способ передать имя столбца не как строку? – kmm 15 April 2010 в 00:13
  • 2
    Вам нужно либо передать имя столбца, указанное как символ, либо целочисленный индекс для столбца. Просто передача B будет предполагать, что B является самим объектом. – Shane 15 April 2010 в 00:14
  • 3
    Понимаю. Я не уверен, как я закончил с запутанным заменителем, eval и т. Д. – kmm 15 April 2010 в 00:17
  • 4
    Вы ищете максимальное значение всех значений из вектора B? который содержится в другом векторе «A» Или вы хотите применить функцию к набору столбцов из фрейма данных? – Shane 15 April 2010 в 00:20
  • 5
    Функция фактически не имеет ничего общего с макс. Это было именно то, что пришло мне в голову, когда я пытался написать пример. – kmm 15 April 2010 в 00:22

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

Предположим, что у нас очень простой фрейм данных:

dat <- data.frame(x = 1:4,
                  y = 5:8)

, и мы хотели бы написать функцию, которая создает новый столбец z, который представляет собой сумму столбцов x и y.

Очень распространенный камень преткновения здесь состоит в том, что естественная (но некорректная) попытка часто выглядит так:

foo <- function(df,col_name,col1,col2){
      df$col_name <- df$col1 + df$col2
      df
}

#Call foo() like this:    
foo(dat,z,x,y)

Проблема здесь в том, что df$col1 t оценить выражение col1. Он просто ищет столбец в df, буквально называемый col1. Это поведение описано в ?Extract в разделе «Рекурсивные (похожие на список) объекты».

Самое простое и наиболее часто рекомендуемое решение - это просто переключиться с $ на [[ и передать аргументы функции как строки:

new_column1 <- function(df,col_name,col1,col2){
    #Create new column col_name as sum of col1 and col2
    df[[col_name]] <- df[[col1]] + df[[col2]]
    df
}

> new_column1(dat,"z","x","y")
  x y  z
1 1 5  6
2 2 6  8
3 3 7 10
4 4 8 12

Это часто считается «лучшей практикой», так как это самый сложный метод. Передача имен столбцов в виде строк примерно такая же однозначная, как вы можете получить.

Следующие два варианта более продвинутые. Многие популярные пакеты используют эти методы, но использование их хорошо требует большей осторожности и умения, поскольку они могут вводить тонкие сложности и непредвиденные точки отказа. Этот раздел книги Хэдли Advanced R является отличной ссылкой для некоторых из этих проблем.

Если вы действительно хотите сохранить пользователя от ввода всех этих кавычки, одним из вариантов может быть преобразование голой, некотируемых имен столбцов в строки с помощью deparse(substitute()):

new_column2 <- function(df,col_name,col1,col2){
    col_name <- deparse(substitute(col_name))
    col1 <- deparse(substitute(col1))
    col2 <- deparse(substitute(col2))

    df[[col_name]] <- df[[col1]] + df[[col2]]
    df
}

> new_column2(dat,z,x,y)
  x y  z
1 1 5  6
2 2 6  8
3 3 7 10
4 4 8 12

Это, откровенно говоря, немного глупо, возможно, так как мы действительно делаем то же самое, что и в new_column1, просто с кучей дополнительной работы, чтобы преобразовать простые имена в строки.

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

new_column3 <- function(df,col_name,expr){
    col_name <- deparse(substitute(col_name))
    df[[col_name]] <- eval(substitute(expr),df,parent.frame())
    df
}

Просто для удовольствия я все еще использую deparse(substitute()) для имени нового столбца , Здесь будет работать все следующее:

> new_column3(dat,z,x+y)
  x y  z
1 1 5  6
2 2 6  8
3 3 7 10
4 4 8 12
> new_column3(dat,z,x-y)
  x y  z
1 1 5 -4
2 2 6 -4
3 3 7 -4
4 4 8 -4
> new_column3(dat,z,x*y)
  x y  z
1 1 5  5
2 2 6 12
3 3 7 21
4 4 8 32

Итак, короткий ответ в основном: передать имена столбцов data.frame в виде строк и использовать [[ для выбора отдельных столбцов. Только начинайте разбираться в eval, substitute и т. Д., Если вы действительно знаете, что делаете.

47
ответ дан Ben Bolker 18 August 2018 в 06:43
поделиться

Лично я считаю, что передача столбца в виде строки довольно уродливая. Мне нравится делать что-то вроде:

get.max <- function(column,data=NULL){
    column<-eval(substitute(column),data, parent.frame())
    max(column)
}

, которое даст:

> get.max(mpg,mtcars)
[1] 33.9
> get.max(c(1,2,3,4,5))
[1] 5

Обратите внимание, что спецификация data.frame является необязательной. вы можете даже работать с функциями ваших столбцов:

> get.max(1/mpg,mtcars)
[1] 0.09615385
19
ответ дан Ian Fellows 18 August 2018 в 06:43
поделиться
  • 1
    Вам нужно выбраться из привычки думать, что использование цитат является уродливым. Не использовать их некрасиво! Зачем? Поскольку вы создали функцию, которую можно использовать только в интерактивном режиме - с ней очень сложно программировать. – hadley 15 April 2010 в 14:21
  • 2
    Я рад, что мне показали лучший способ, но я не вижу разницы между этим и qplot (x = mpg, data = mtcars). ggplot2 никогда не пропускает столбец как строку, и я думаю, что для него лучше. Почему вы говорите, что это можно использовать только в интерактивном режиме? В какой ситуации это приведет к нежелательным результатам? С чем сложнее программировать? В теле сообщения я показываю, насколько он более гибкий. – Ian Fellows 15 April 2010 в 16:44
  • 3
    5 лет спустя -) .. Зачем нам нужно: parent.frame ()? – mql4beginner 21 June 2015 в 11:48
  • 4
    7 лет спустя: не использует котировки, все еще уродливые? – Spacedman 31 October 2017 в 09:02
Другие вопросы по тегам:

Похожие вопросы: