R: + = (cộng bằng) và ++ (cộng cộng) tương đương từ c ++ / c # / java, v.v.?


Câu trả lời:



64

Theo dõi @ GregaKešpret, bạn có thể tạo một toán tử infix:

`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x

6
(+1), nhưng một lời cảnh báo. Gõ x = %+=% y/2trả lại x = (x + y)/2. Thêm dấu ngoặc đơn, tức là x = %+=% (y/2)giải quyết vấn đề.
knrumsey

@knrumsey Tại sao vậy? Tôi đã đoán phân chia sẽ là một toán tử ưu tiên cao hơn.
David Kelley

@DavidKelley Không chắc chắn. Tôi với bạn ở đó. Tôi đã gặp vấn đề này khi làm việc trên một dự án một lần và tôi phải mất một giờ để tìm ra vấn đề.
knrumsey

Hãy nhớ rằng bạn đang chạy một chức năng, không thực hiện một bổ sung. Các hàm có quyền ưu tiên cao nhất vì vậy không có dấu ngoặc đơn, nó phân tích cú pháp y làm đầu vào hàm với phân chia là bước tiếp theo trong chuỗi. Dấu ngoặc đơn nâng hoạt động (y / 2) lên đầu chuỗi.
Justin

33

R không có khái niệm về increment operator(ví dụ ++ trong C). Tuy nhiên, không khó để tự thực hiện một ví dụ:

inc <- function(x)
{
 eval.parent(substitute(x <- x + 1))
}

Trong trường hợp đó bạn sẽ gọi

x <- 10
inc(x)

Tuy nhiên, nó giới thiệu chức năng gọi qua đầu, vì vậy nó chậm hơn so với x <- x + 1tự nhập . Nếu tôi không nhầm increment operatorđược giới thiệu để làm cho trình biên dịch dễ dàng hơn, vì nó có thể chuyển đổi mã thành các hướng dẫn ngôn ngữ máy đó trực tiếp.


3
Hàm này không thể trả về giá trị và sau đó tăng dần như một postincrement ++. Nó tương tự như + = hoặc preincrement ++.
Megatron

Sai lầm! Tăng không được giới thiệu để làm cho công việc biên dịch dễ dàng hơn. INChướng dẫn được giới thiệu trong các bộ xử lý chủ yếu để thực hiện các bộ đếm (xem Hướng dẫn dành cho nhà phát triển phần mềm Intel). Tôi sẽ cập nhật câu trả lời.
banan3'14

19

R không có các thao tác này vì (hầu hết) các đối tượng trong R là bất biến. Họ không thay đổi. Thông thường, khi có vẻ như bạn đang sửa đổi một đối tượng, bạn thực sự đang sửa đổi một bản sao.


18
Mặc dù tính bất biến là một thuộc tính tuyệt vời / mong muốn cho các đối tượng (đọc: ít lỗi hơn) Tôi không nghĩ tính bất biến liên quan đến câu hỏi + =. Trong các ngôn ngữ khác + = có thể được áp dụng cho các loại không thay đổi (như chuỗi trong .net). Hoạt động chỉ đơn giản là tạo một đối tượng mới và gán biến đã cho cho đối tượng mới đó. Tính bất biến được duy trì và biến được cập nhật.
SFun28

4
Điểm tốt. Tuy nhiên, tính bất biến chắc chắn làm cho loại hoạt động này ít tự nhiên hơn.
hadley

15

Tăng và giảm 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Các chức năng này dường như đã bị xóa khỏi Hmiscphiên bản 4.1.0.
llasram

@llasram nhìn vào ký hiệu đó, tôi không thể trách ai được.
bers


3

Chúng tôi có thể ghi đè +. Nếu unary +được sử dụng và đối số của nó là một +lệnh gọi unary , sau đó tăng biến có liên quan trong môi trường gọi.

`+` <- function(e1,e2){
    # if unary `+`, keep original behavior
    if(missing(e2)) {
      s_e1 <- substitute(e1)
      # if e1 (the argument of unary +) is itself an unary `+` operation
      if(length(s_e1) == 2 && 
         identical(s_e1[[1]], quote(`+`)) && 
         length(s_e1[[2]]) == 1){
        # increment value in parent environment
        eval.parent(substitute(e1 <- e1 + 1,list(e1 = s_e1[[2]])))
      # else unary `+` should just return it's input
      } else e1
    # if binary `+`, keep original behavior
    } else .Primitive("+")(e1,e2)
}

x <- 10
++x
x
# [1] 11

các hoạt động khác không thay đổi:

x + 2
# [1] 13
x ++ 2
# [1] 13
+x
# [1] 11
x
# [1] 11

Đừng làm điều đó vì bạn sẽ làm chậm mọi thứ. Hoặc thực hiện trong môi trường khác và đảm bảo bạn không có các vòng lặp lớn theo các hướng dẫn này.

Bạn cũng có thể làm điều này:

`++` <- function(x) eval.parent(substitute(x <-x +1))
a <- 1
`++`(a)
a
# [1] 2

-1

Có một cách khác để làm điều này, mà tôi thấy rất dễ dàng, có thể là một số trợ giúp

Tôi sử dụng <<-cho các tình huống này Các toán tử <<-gán giá trị cho môi trường cha

inc <- function(x)
{
   x <<- x + 1
}

và bạn có thể gọi nó như thế

x <- 0
inc(x)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.