2013-07-18 2 views
0

Многие учебники R поощряют использование $ для извлечения переменных (столбцов) из data.frames ^. Однако я обнаружил, что это не работает внутри функции, и я не могу понять, почему.

data(BOD) 
print(BOD) 

# These work. 
BOD$'demand' 
BOD[ ,'demand'] 

# This works. 
myFunc1 <- function(x, y){ 
    z <- x[ , y] 
    return(z) 
} 
out <- myFunc(BOD, 'demand') 

# This doesn't work. 
myFunc2 <- function(x, y){ 
    z <- x$y 
    return(z) 
} 
out <- myFunc2(BOD, 'demand') 

Я заметил, что в R Язык определении говорится:

формы с помощью $ относится к рекурсивным объектам, таким как списки и pairlists. Он допускает только буквенную> символьную строку или символ в качестве индекса. То есть индекс не является вычислимым: для случаев, когда> вам нужно оценить выражение для поиска индекса, используйте x [[expr]]. Когда $ применяется к нерекурсивному объекту, результат всегда был NULL: как из R 2.6.0 это ошибка.

Является ли myFunc2 выше примера, где $ не предоставляется буквальная строка символов?

^Zuur 2009 'Руководство для начинающих R' р 61

^'Манипулирование данными с R' Spector 2008 р 26, 64, 69

+3

То, что вы делаете внутри функции, не работает вне функций: 'y = 'demand'; z = BOD $ y' – Marius

+2

'fortune (312)' здесь снова имеет значение: «Проблема здесь в том, что нотация $ является магическим ярлыком и, как и любая другая магия, если используется , неверно, скорее всего, сделает программный эквивалент превращения себя в жабу " – thelatemail

ответ

3

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

myFunc2 <- function(x, y){ 
    z <- do.call('$',list(x,y)) 
    return(z) 
} 
myFunc2(BOD,'demand') 
[1] 8.3 10.3 19.0 16.0 15.6 19.8 

Но здесь проще использовать [, как вы уже упоминали:

myFunc2 <- function(x, y){ 
    z <-  x[,y] 
    return(z) 
} 
4

Вы также можете использовать [[вместо $

myFunc2 <- function(x, y){ 
+  z <- x[[y]] 
+  return(z) 
+ } 
> myFunc2(BOD, 'demand') 
[1] 8.3 10.3 19.0 16.0 15.6 19.8 
1

Если вы хотите, чтобы полностью имитировать $ оператора вы можете использовать [[ и установить в год rameter exact - FALSE, чтобы обеспечить частичное совпадение.

BOD <- data.frame(demand = 1:10) 

myFunc2 <- function(x, y) x[[y, exact = FALSE]] 

BOD$dem 
## [1] 1 2 3 4 5 6 7 8 9 10 

BOD[["dem"]] 
## NULL 

myFunc2(BOD, "dem") 
## [1] 1 2 3 4 5 6 7 8 9 10 
Смежные вопросы