2012-03-02 38 views
9

Tôi đang tìm cách tạo biểu thức là sản phẩm của hai biểu thức đã cho. Ví dụ, giả sử tôi cóThao tác các biểu thức trong R

e1 <- expression(a+b*x) 
e2 <- expression(c+d*x) 

Bây giờ tôi muốn tạo programatically biểu thức (e1)*(e2):

expression((a+b*x)*(c+d*x)) 

nền Tôi viết một chức năng mô hình phù hợp. Mô hình có hai phần được người dùng xác định. Tôi cần để có thể "xử lý" chúng một cách riêng biệt, và sau đó tạo ra một biểu thức kết hợp và "xử lý" nó như là một mô hình. "Xử lý" liên quan đến việc sử dụng các dẫn xuất số và hàm deriv muốn biểu thức làm đầu vào.

+0

Lưu ý: nếu bạn ở trong tình huống tương tự nhưng không yêu cầu 'biểu thức' cho đầu ra, hãy tạo hàm thay thế và sử dụng' body' để sửa đổi nội dung của hàm. –

Trả lời

5

Tôi không đối phó với điều này quá thường xuyên nhưng một cái gì đó như thế này dường như được làm việc

e1 <- expression(a + b*x) 
e2 <- expression(c + d*x) 
substitute(expression(e1*e2), list(e1 = e1[[1]], e2 = e2[[1]])) 
# expression((a + b * x) * (c + d * x)) 
+0

Cảm ơn, đây là những gì tôi cần. Các dấu ngoặc đơn trong '(e1) * (e2)' thậm chí không cần thiết - R là đủ thông minh để đặt chúng vào. – Aniko

+0

Bạn nói đúng! Tôi sẽ chỉnh sửa câu trả lời đó. – Dason

5

Hãy thử điều này:

e1 <- quote(a+b*x) # or expression(*)[[1]] 
e2 <- quote(c+d*x) 
substitute(e1 * e2, list(e1=e1, e2=e2)) 
+0

Cảm ơn! Tôi chấp nhận câu trả lời của Dason, về cơ bản là cùng một ý tưởng, bởi vì anh ta đã trả lời câu hỏi chính xác được hỏi, nhưng câu trả lời này cung cấp thêm cái nhìn sâu sắc. – Aniko

2

Đây có thể là quá mức cần thiết trong trường hợp của bạn, nhưng gói Ryacas thể được tốt đẹp để thực hiện các thao tác biểu tượng phức tạp hơn của loại này:

library(Ryacas) 
yacas(expression(e1*e2))$text 
# expression((a + b * x) * (c + d * x)) 

A LSO, thay vì sử dụng substitute(), bạn có thể xây dựng các biểu hiện tương tự trong cơ sở R như thế này:

as.expression(as.call(list(as.symbol("*"), e1[[1]], e2[[1]]))) 
# expression((a + b * x) * (c + d * x)) 

Chú giải: Một khía cạnh ban đầu khó hiểu đối phó với expression đối tượng là họ đang thực sự danh sách của ngôn ngữ các đối tượng - ngay cả khi (như thường là trường hợp) các danh sách đó chỉ chứa một đối tượng. Ví dụ: trong câu hỏi của bạn, cả hai số e1e2 là độ dài 1 danh sách có chứa một đối tượng call duy nhất.

Làm việc từ trong ra ngoài, đoạn code trên:

  1. chiết xuất từ ​​hai call đối tượng sử dụng [[1]]
  2. Sử dụng as.call() để xây dựng một cuộc gọi mới đó là sản phẩm của hai call đối tượng.
  3. Cuối cùng, kết thúc kết quả call sao lưu làm đối tượng expression mà bạn muốn.
+0

Vâng, tôi đã thử chơi với biểu thức như một danh sách, nhưng không thể làm cho nó hoạt động. Không có thắc mắc, điều này là khó khăn. – Aniko

+0

Không nghi ngờ gì. Nó chỉ bắt đầu có ý nghĩa với tôi sau ~ 5 năm làm việc với ngôn ngữ trên cơ sở khá thường xuyên. Tốt nhất của may mắn xây dựng chức năng của bạn. –