R:如何在函数中通过 $ 而不是 [] 进行索引?

R: how to index by $ instead of [] in a function?

我正在编写一个 R 函数,它将数据框和变量名作为输入,对数据框中与输入变量名对应的向量执行一些操作,然后 returns 结果向量。

虽然我可以使用 [] 来编写此函数以进行索引,但我正在尝试学习如何使用 $ 进行索引(我知道这可能是个坏主意)。

我最好的猜测是我需要将我想要的字符串粘贴在一起并以某种方式使用 parse()eval()substitute() 或其他一些函数,但我怀疑那里可能是更好的方法。感谢任何帮助。

# Create an arbitrary data frame
df <- data.frame(x = c("a","b","c","c","c"),
                 y = 1:5,
                 z = c(1,9,NA,0,NA))

# Create a vector with character "y",
# capturing the name of the column
# I want to work with in my data
M <- "y"

# Write a function that takes a 
# data frame and a variable name,
# adds 5 to each value of that 
# variable in the data frame, then
# prints the resulting numeric vector.
# Below produces the desired output
# of the function:
print(df$y + 5)

#####################################
# Define function to add 5 to a specified
# variable in the data frame using [] indexing
fun1 <- function(dat, var) {
    df[ ,var] + 5
}

# Works with both quoted values and
# objects assigned quoted values
fun1(dat = df, var = "y")
fun1(dat = df, var = M)

# However, doesn't work when I use 
# $ instead of []. See function below
# and corresponding results.
fun2 <- function(dat, var) {
  df$var + 5
}

# Doesn't produce intended result
fun2(dat = df, var = "y")
fun2(dat = df, var = M)

你可以的。你真的不应该,但你可以。

与 R 中的所有运算符一样,$ 实际上是一个函数。它的第一个参数是一个列表(可能但不一定是 class data.frame),第二个参数是一个名称(“symbol”类型的对象)。由于 $ 不评估第二个参数,如果您打算以编程方式传递它,则需要替换它。

我会这样做:

fun2 <- function(dat, var) {
  var <- as.name(var)
  eval(substitute("$"(dat, var) + 5))
  }

fun2(dat = df, var = "y")
#[1]  6  7  8  9 10
fun2(dat = df, var = M)
#[1]  6  7  8  9 10

如果您像 R 开发人员预期的那样使用 [,看看这有多好?