我有一个字符串如下
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
中的对应符号,但我真的不知道如何获取该符号,
实例lapply(names(vec), grepl, str)
我只能看到字符串中的哪个变量。
是否有更简单的方法,例如使用formula
或expression
?我还查看了包Ryacas
,但找不到我需要的内容。
答案 0 :(得分: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"
?如果没有,你将不得不单独处理。
答案 1 :(得分: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)
答案 2 :(得分: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
答案 3 :(得分: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
中的值会告诉您字符串中变量的符号。
丑陋而有趣的设计: - )