Как я могу использовать имена переменных для ссылки на столбцы фрейма данных с помощью ddply? - PullRequest
4 голосов
/ 15 января 2012

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

Когда я использую имя столбца напрямую с ddply и cumsum, у меня нет проблем:

require(plyr)
df <- data.frame(date = seq(as.Date("2007/1/1"),
                     by = "month",
                     length.out = 60),
                 sales = runif(60, min = 700, max = 1200))

df$year <- as.numeric(format(as.Date(df$date), format="%Y"))
df <- ddply(df, .(year), transform,
            cum_sales = (cumsum(as.numeric(sales))))

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

mycol <- "sales"
df[mycol]

df <- ddply(df, .(year), transform,
            cum_value2 = cumsum(as.numeric(df[mycol])))

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

У меня есть два вопроса.

  1. Что я делаю неправильно, то есть что я неправильно понял?
  2. Есть ли лучший способ сделать это, помнячто имена столбцов не будут заранее известны функции?

TIA

Ответы [ 2 ]

7 голосов
/ 15 января 2012

Аргументы для ddply - это выражения, которые оцениваются в контексте каждой части, на которую разбивается исходный фрейм данных.Ваш df [myval] обращается ко всему фрейму данных, поэтому вы не можете передать его как есть (кстати, зачем вам эти as.numeric (as.character ()) вещи - они абсолютно бесполезны).* Самый простой способ - написать свою собственную функцию, которая будет делать все внутри, и передать имя столбца, например,

df <- ddply(df, 
            .(year), 
            .fun = function(x, colname) transform(x, cum_sales = cumsum(x[,colname])), 
            colname = "sales")
1 голос
/ 15 января 2012

Проблема в том, что ddply ожидает, что его последними аргументами будут выражения, которые будут оцениваться на фрагментах data.frame (каждый год, в вашем примере). Если вы используете df[myval], у вас есть весь data.frame, а не годовые куски.

Следующее работает, но не очень элегантно: я строю выражение как строку, а затем преобразую его с помощью eval(parse(...)).

ddply( df, .(year), transform, 
  cum_value2 = eval(parse( text = 
    sprintf( "cumsum(as.numeric(as.character(%s)))", mycol )
  ))
)
...