以例如:
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)
来实现,但如果字符串很长,则不优雅。
答案 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