3

我有一个字符串如下

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并使用正则表达式来提取相应的符号 in str,但我真的不知道如何获取符号,例如lapply(names(vec), grepl, str)我只能看到哪些变量在字符串中.

有没有更简单的方法,例如使用formulaor expression?我还查看了包裹Ryacas,但找不到我需要的东西。

4

4 回答 4

4

这适用于您的示例:

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

vec[vars] <- ifelse(signs == "+", 1, -1)

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

于 2013-10-14T16:08:07.067 回答
3

用于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)
于 2013-10-14T16:22:13.107 回答
2

我喜欢这种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 
于 2013-10-14T16:18:48.243 回答
1

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

# 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将告诉您字符串中变量的符号。丑陋但有趣的设计:-)

于 2013-10-14T17:28:47.657 回答