【问题标题】:Extract algebraic signs from string从字符串中提取代数符号
【发布时间】:2013-10-14 16:01:25
【问题描述】:

我有一个字符串如下

str <- "- var_a + var_c - var_d"

我想改变向量vec中的值

 vec <- c(var_a=0, var_b=0, var_c=0, var_d=0, var_e=0)
 vec
 var_a var_b var_c var_d var_e 
    0     0     0     0     0 

根据str:每当变量有负号时,将vec中的相应条目设置为-1,如果它有一个正号为1。我想要的输出如下所示:

var_a var_b var_c var_d var_e 
   -1     0     1    -1     0

我的想法是尝试遍历vec 的所有名称并使用正则表达式提取str 中的对应符号,但我真的不知道如何获取符号,使用 for instance lapply(names(vec), grepl, str) 只能看到字符串中有哪些变量。

难道没有更简单的方法,例如 formulaexpression 吗?我还查看了包裹Ryacas,但找不到我需要的东西。

【问题讨论】:

    标签: string r extract formula


    【解决方案1】:

    这适用于您的示例:

    splitted <- strsplit(str, " ")[[1]]
    signs <- splitted[c(TRUE, FALSE)]
    vars  <- splitted[c(FALSE, TRUE)]
    
    vec[vars] <- ifelse(signs == "+", 1, -1)
    

    第一个变量上的第一个符号是正数吗,你会像 str &lt;- "+ var_a + var_c - var_d" 那样有一个前导 + 吗?如果没有,您将不得不单独处理。

    【讨论】:

    • 两种情况都可能发生,要么什么都没有,要么后面有一个“+”,这就有点复杂了。
    • 不是真的,只需添加if (length(splitted) %% 2) splitted &lt;- c('+', splitted)。抱歉,我没有立即跟进(我希望有人这样做),因为我不在电脑附近。
    【解决方案2】:

    使用scan 读取和拆分数据。扫描读取数据并将其放入向量中。

    vec <- c(var_a=0, var_b=0, var_c=0, var_d=0, var_e=0)
    ll <- scan(text=str,what='string')
    ## EDIT here to treat the case the first elment is not a sign
    ## i.e: var_a + var_c - var_d
    pos <- ll %in% c('-','+')
    if(length(ll[pos]) != length(ll[!pos])) ll <- append(ll,'+',0)
    vec[ll[!pos]] <- ifelse(ll[pos] == '-',-1,1)
    

    【讨论】:

    • 这也为"var_a + var_c - var_d""+ var_a + var_c - var_d" 提供了正确的结果
    • @user1981275 恐怕不是。不,在我编辑后它应该适用于这两种情况。
    【解决方案3】:

    我喜欢regex 方法,但您必须注意正则表达式与您的变量名兼容。这会将字符串拆分为以字母字符开头的空格(您可以使用[[:alphanum:]] 更灵活,但我不确定您的字符串中是否包含数字...

    #  Split variables
    args <- strsplit( str , "(?<=[a-z])\\s" , perl = TRUE )[[1]]
    
    #  Extract sign and convert to integer
    sign <- as.integer( paste0( strtrim(args , 1 ) , 1 ) )
    
    # Match and change the corresponding values of vec
    vec[ match( substring( args , first = 3 ) , names(vec) ) ] <- sign
    #var_a var_b var_c var_d var_e 
    #   -1     0     1    -1     0 
    

    【讨论】:

    • +1 为正则表达式的使用!这始终是一项具有挑战性的任务。
    【解决方案4】:

    我正在考虑一种可能缓慢的方法

    # set up initial condition
    var_a<-var_b<-var_c<-etc<-0
     varnames<-c('var_a','var_b','var_c', etc)
    
    values<-rep(0,length(varnames))
    # test one by one to see what you get, w/ apologies in advance for evalparse
    for (j in 1: length(varnames) ) {
        assign(varnames[j],1)
        values[j]<- eval(parse(str))
        assign(varnames[j],0)
    }
    

    然后values 中的值将告诉您字符串中变量的符号。 丑陋但有趣的设计:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-12
      • 2014-07-15
      • 2011-11-04
      • 2011-09-10
      • 2017-12-31
      • 1970-01-01
      • 2019-12-13
      • 2013-05-24
      相关资源
      最近更新 更多