【问题标题】:How to convert a string in a function into an object?如何将函数中的字符串转换为对象?
【发布时间】:2011-11-19 18:07:22
【问题描述】:

我想将我在函数中传递的字符串转换为对象(或列名)。

我知道这行得通:

df <- data.frame(A = 1:10, B = 11:20)

test.function <- function(x)            
{
  z <- df[[x]]
  return(z)
}
test.function("A")

我不想使用 [[.]] 运算符,因为有时它不切实际甚至不适用。我对将字符串转换为“对象”的通用方法感兴趣。因此我尝试了以下方法:

df <- data.frame(A = 1:10, B = 11:20)

test.function <- function(x)
{
  z <- get(paste("df$", x, sep = ""))
  return(z)
}
test.function("A")

df <- data.frame(A = 1:10, B = 11:20)

test.function <- function(x)
{
  z <- as.name(paste("df$", x, sep = ""))
  return(z)
}
test.function("A")

df <- data.frame(A = 1:10, B = 11:20)

test.function <- function(x)
{
  z <- df$as.name(x)
  return(z)
}
test.function("A")

我还尝试使用 parse、do.call 和 eval 函数。可惜我失败了

【问题讨论】:

    标签: r


    【解决方案1】:

    诀窍是使用parse。例如:

    > x <- "A"
    > eval(parse(text=paste("df$", x, sep = "")))
     [1]  1  2  3  4  5  6  7  8  9 10
    

    另请参阅此问答:Evaluate expression given as a string

    【讨论】:

    • 如果答案是 parse() 你通常应该重新考虑这个问题。 ——Thomas Lumley R-help(2005 年 2 月)—— PS,我投了赞成票,因为我也想不出更好的方法 :)
    • @JDLong 是的,使用[ 按列名进行常规索引对我来说总是足够的。然后你可以取一列,或者 2,或者其他什么...
    【解决方案2】:

    我刚刚得到了一个支持,这让我在 5 年后重新回答了这个问题。我仍然认为正确的答案是[[,尽管 OP 要求不要使用它,但这是一种将[[ 打扮成更实用的“功能”的方法。

    df <-     structure(list(x = 1:3, y = 1:3), .Names = c("x", "y"), row.names = c(NA, 
    -3L), class = "data.frame")
    
     test.function <- `[[`    # So simple, `test.function` now has all the features desired.
     df
     x y
     1 1
     2 2
     3 3
     test.function(df, "x")
    #[1] 1 2 3
    

    或者,如果需要硬编码从调用环境中提取一个名为“df”的对象,这个命题似乎安全性值得怀疑:

     test.df_txt <- function(var, dfn ='df' ){ get(dfn)[[var]] }
     test.df_txt("x")
    #[1] 1 2 3
    

    原始回复(仍然不推荐):

    如果您愿意使用 eval(parse(text=...)) ,则可以避开“$”的限制:

     test.function <- function(x)  {
       z <- eval(parse( text=paste("df$", x, sep = "")), env=.GlobalEnv)
       return(z)
       }
    test.function("A")
    # [1]  1  2  3  4  5  6  7  8  9 10
    

    但是...使用“[[”要好得多。 (我在eval(parse()-ing 的最初努力被困在没有足够的知识使用parse 的“文本”参数。)

    【讨论】:

      【解决方案3】:

      除了eval(parse(text=YOUR_STRING)),您还可以使用as.symbol 作为潜在的替代方案。

      【讨论】:

      • 是的,eval(as.symbol(YOUR_STRING)) 为我工作。谢谢。
      【解决方案4】:

      您可以使用赋值运算符从字符串创建变量名,如下所示: 赋值("a_string", NULL)

      【讨论】:

        【解决方案5】:

        函数调用很好地完成了你想要的:

        x <- data.frame(a = c(TRUE, FALSE, NA), b = 1:9, c = dnorm(-4:4), d = exp(-4:4 * 1i), `syntaxically invalid name` = LETTERS[1:9], check.names = FALSE)
        
        
        solution <- function (string)
        eval(call(name = "$", quote(x), as.symbol(string)))
        
        
        print(solution("a"))
        print(solution("syntaxically invalid name"))
        

        如果您希望能够指定要从中检索列的对象的名称,请尝试:

        x <- data.frame(a = c(TRUE, FALSE, NA), b = 1:9, c = dnorm(-4:4), d = exp(-4:4 * 1i), `syntaxically invalid name` = LETTERS[1:9], check.names = FALSE)
        y <- x
        y$b <- y$b * 2L
        
        
        solution <- function (object.name, string)
        eval(call(name = "$", as.symbol(object.name), as.symbol(string)))
        
        
        print(solution("x", "b"))
        print(solution("y", "b"))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-03
          • 2018-07-19
          • 1970-01-01
          • 1970-01-01
          • 2019-07-07
          • 1970-01-01
          相关资源
          最近更新 更多