将字符串转换为R中的值

时间:2014-01-02 04:09:37

标签: r

以例如:

s <- c("1y1","2y1","1.5y2","1.8y2")

y1和y2表示乘以2和1.8。

1y1 = 1*2=2    
1.5y2 = 1.5*1.8 = 2.7     

因此,结果将是c(2,4,2.7,3.24) 我怎么才能得到它?

我可以通过c(1,2.5,3,2.7)*c(2,2,1.8,1.8)来实现,但如果字符串很长,则不优雅。

3 个答案:

答案 0 :(得分:3)

你可以试试这个:

s = sub(pattern="y", replacement="*y", x=s)

sub将用y替换*y的所有出现次数,因此表达式在语法上对R来说是正确的。但是,它实际上不是表达式而是字符向量。注意sub将仅替换y的第一个发生。如果每个字符串有多个“y”,则必须使用gsub。有关详细信息,请参阅?sub

y1 = 2
y2 = 1.8

s = parse(text=s) # parse will convert s to a R expression
s.num = sapply(s, eval) # and this will evaluate the expression to give the results

[1] 2.00 4.00 2.70 3.24

答案 1 :(得分:3)

使用gsub将y1和y2替换为各自的数值,然后可以使用经典eval(parse(..))来计算结果数值表达式。

s <- c("1y1","2y1","1.5y2","1.8y2")

s <- gsub('y1','*2',s)
s <-gsub('y2','*1.8',s)

sapply(s,function(x)eval(parse(text=x)))
1*2     2*2 1.5*1.8 1.8*1.8 
2.00    4.00    2.70    3.24 

EDIT 使用gsubfn的更优雅的选项,以及灵活的功能替换版本。

> library(gsubfn)
> sub.f <- function(x,y) as.numeric(x) * ifelse(y == 1, 2, 1. 8)
> as.numeric(gsubfn('(.*)y(.*)', sub.f, s))
 [1] 2.00 4.00 2.70 3.24

我们将每个表达式拆分为2个组件x和y并使用它们(一旦强制转换为数字)来手动计算表达式。

或者,这一个班轮:

> strapply(s, '(.*)y(.*)', ~ as.numeric(x) * ifelse(y == 1, 2, 1.8), simplify = TRUE)
[1] 2.00 4.00 2.70 3.24

答案 2 :(得分:1)

这是另一个想法:

s <- c("1y1", "2y1", "1.5y2", "1.8y2")
s2 <- as.numeric(sub("y[0-9]", "", s))

mult <- rep(NA, len = length(s))
mult[grep("y1", s)] <- 2
mult[grep("y2", s)] <- 1.8

s2 * mult
#[1] 2.00 4.00 2.70 3.24

规模更大:

S = sample(s, 1e4, T)
f1 = function() {
      S <- gsub('y1','*2',S)
      S <-gsub('y2','*1.8',S)
      sapply(S,function(x)eval(parse(text=x)))
     }
f2 = function() {
        S = sub(pattern="y", replacement="*y", x=S)
        S = parse(text=S) 
        S.num = sapply(S, eval)
        S.num
     } ; y1 = 2 ; y2 = 1.8
f3 = function() {
      s2 <- as.numeric(sub("y[0-9]", "", S))
      mult <- rep(NA, len = length(S))
      mult[grep("y1", S)] <- 2
      mult[grep("y2", S)] <- 1.8
      s2 * mult
     }
library(microbenchmark)
microbenchmark(f1(), f2(), f3(), times = 10)
#Unit: milliseconds
# expr        min         lq    median         uq        max neval
# f1() 1940.63876 2037.03500 2064.4605 2072.98875 2101.73358    10
# f2()   93.43298   98.69724  115.8716  125.07774  153.43385    10
# f3()   12.91724   13.01781   13.1805   13.30283   17.94973    10
sum(f1() != f2())
#[1] 0
sum(f2() != f3())
#[1] 0