Như câu hỏi đặt ra, có một chuỗi điều khiển trong R tương tự như của C ternary operator? Nếu vậy, làm thế nào để bạn sử dụng nó? Cảm ơn!Toán tử bậc ba có tồn tại trong R không?
Trả lời
Như if
là chức năng trong R
và trả về đánh giá mới nhất, if-else tương đương với ?:
.
> a <- 1
> x <- if(a==1) 1 else 2
> x
[1] 1
> x <- if(a==2) 1 else 2
> x
[1] 2
Sức mạnh của R là vector. Các vector của các nhà điều hành ternary là ifelse
:
> a <- c(1, 2, 1)
> x <- ifelse(a==1, 1, 2)
> x
[1] 1 2 1
> x <- ifelse(a==2, 1, 2)
> x
[1] 2 1 2
Just kidding, bạn có thể xác định c kiểu ?:
:
`?` <- function(x, y)
eval(
sapply(
strsplit(
deparse(substitute(y)),
":"
),
function(e) parse(text = e)
)[[2 - as.logical(x)]])
đây, bạn không cần phải chăm sóc về dấu ngoặc:
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
> TRUE ? x*2 : 0
[1] 2
> FALSE ? x*2 : 0
[1] 0
nhưng bạn cần dấu ngoặc để chuyển nhượng :(
> y <- 1 ? 2*3 : 4
[1] 6
> y
[1] 1
> y <- (1 ? 2*3 : 4)
> y
[1] 6
Cuối cùng, bạn có thể làm theo cách rất giống với c:
`?` <- function(x, y) {
xs <- as.list(substitute(x))
if (xs[[1]] == as.name("<-")) x <- eval(xs[[3]])
r <- eval(sapply(strsplit(deparse(substitute(y)), ":"), function(e) parse(text = e))[[2 - as.logical(x)]])
if (xs[[1]] == as.name("<-")) {
xs[[3]] <- r
eval.parent(as.call(xs))
} else {
r
}
}
Bạn có thể thoát khỏi dấu ngoặc:
> y <- 1 ? 2*3 : 4
> y
[1] 6
> y <- 0 ? 2*3 : 4
> y
[1] 4
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
Đây không phải là để sử dụng hàng ngày, nhưng có lẽ tốt cho việc học một số nội ngữ của ngôn ngữ R.
Tôi sẽ xem xét lệnh ifelse
. Tôi sẽ gọi nó tốt hơn vì nó cũng được vector hóa. Ví dụ sử dụng tập dữ liệu ô tô:
> cars$speed > 20
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
[49] TRUE TRUE
> ifelse(cars$speed > 20, 'fast', 'slow')
[1] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[11] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[21] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[31] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[41] "slow" "slow" "slow" "fast" "fast" "fast" "fast" "fast" "fast" "fast"
Xin chào Paul - bạn có muốn nói điều gì đó về 'ifelse' với ví dụ của bạn không?;) –
Không có ý định chơi chữ, nhưng nó có thể không chủ ý;) –
Liên kết của bạn trỏ đến tuyên bố if
.
> x <- 1
> if(x < 2) print("Less than") else print("Greater than")
[1] "Less than"
Nếu biến đầu vào của bạn là một vector, sau đó ifelse
có thể phù hợp hơn:
> x <- 1:3
> ifelse(x<=2, "Less than or equal", "Greater than")
[1] "Less than or equal" "Less than or equal" "Greater than"
Để truy cập vào trang trợ giúp cho if
, bạn cần phải nhúng các if
trong backticks:
?`if`
Trang trợ giúp cho ifelse
là một t:
`?ifelse`
Như @kohske đã nói, điều này cũng sẽ hoạt động: 'print (if (x <2)" Less than "else" Greater than ")' –
Nó không rõ ràng tồn tại, nhưng bạn có thể làm:
set.seed(21)
y <- 1:10
z <- rnorm(10)
condition1 <- TRUE
x1 <- if(condition1) y else z
hoặc
condition2 <- sample(c(TRUE,FALSE),10,TRUE)
x2 <- ifelse(condition2, y, z)
Sự khác biệt giữa hai là condition1
phải là một vector logic có độ dài 1, trong khi condition2
phải là một vectơ lôgic có cùng độ dài như x
, y
và z
. Đầu tiên sẽ trả lại hoặc là y
hoặc z
(toàn bộ đối tượng), trong khi cột thứ hai sẽ trả về phần tử tương ứng của y
(condition2==TRUE
) hoặc z
(condition2==FALSE
).
Cũng lưu ý rằng ifelse
sẽ chậm hơn so if
/else
nếu condition
, y
, và z
đều vectơ với chiều dài 1.
thanks Joshua , câu trả lời của bạn đã giúp ích rất nhiều, tôi đã tìm thấy câu trả lời từ bài đăng bạn đã đề cập http://stackoverflow.com/a/8792474/3019570 –
Giống như mọi người khác nói, sử dụng ifelse
, nhưng bạn có thể xác định các nhà khai thác để bạn gần có cú pháp toán tử bậc ba.
`%?%` <- function(x, y) list(x = x, y = y)
`%:%` <- function(xy, z) if(xy$x) xy$y else z
TRUE %?% rnorm(5) %:% month.abb
## [1] 0.05363141 -0.42434567 -0.20000319 1.31049766 -0.31761248
FALSE %?% rnorm(5) %:% month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# or, more generally
condition %?% value1 %:% value2
Nó thực sự hoạt động nếu bạn xác định các nhà khai thác mà không có sự %
dấu hiệu, vì vậy bạn có thể có
`?` <- function(x, y) if(x) y[[1]] else y[[2]]
`:` <- function(y, z) list(y, z)
TRUE ? rnorm(5) : month.abb
## [1] 1.4584104143 0.0007500051 -0.7629123322 0.2433415442 0.0052823403
FALSE ? rnorm(5) : month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
(này làm việc vì ưu tiên của :
thấp hơn ?
.)
Thật không may , sau đó ngắt các toán tử trợ giúp và trình tự hiện có.
Cũng giống như một trò đùa, bạn có thể xác định lại ?
vận hành (hầu như) làm việc như các nhà điều hành ternary (THIS IS A IDEA BAD):
`?` <- function(x, y) { y <-substitute(y); if(x) eval(y[[2]], parent.frame()) else eval(y[[3]], parent.frame()) }
x <- 1:3
length(x) ? (x*2) : 0
x <- numeric(0)
length(x) ? (x*2) : 0
for(i in 1:5) cat(i, (i %% 2) ? "Odd\n" : "Even\n")
... Nhưng bạn cần phải đặt biểu thức trong ngoặc đơn bởi vì ưu tiên mặc định không giống như trong C.
Chỉ cần nhớ để khôi phục lại chức năng giúp đỡ cũ khi bạn đã hoàn tất chơi:
rm(`?`)
if
công trình như ifelse unvectorised nếu được sử dụng theo cách sau:
`if`(condition, doIfTrue, doIfFalse)
Ưu điểm của việc sử dụng này trên ifelse là khi vectorisation là trong cách (ví dụ: Tôi có boolean vô hướng và danh sách/vector điều như vậy)
ifelse(TRUE, c(1,2), c(3,4))
[1] 1
`if`(TRUE, c(1,2), c(3,4))
[1] 1 2
- 1. VHDL có một toán tử bậc ba không?
- 2. Toán tử bậc ba trong JSTL/EL
- 3. Có một toán tử bậc ba trong handlebars.js không?
- 4. Toán tử bậc ba trong LINQ, tại đó khoản
- 5. Tại sao tôi không thể ném ngoại lệ trong khi sử dụng toán tử bậc ba
- 6. Toán tử bậc ba và chuỗi nối quirk?
- 7. Sử dụng toán tử bậc ba cho nhiều thao tác
- 8. Khởi tạo mảng với toán tử bậc ba?
- 9. Toán tử bậc ba + hàm tạo C++ 11 từ initializer_list
- 10. Toán tử bậc ba: thực hành tốt hay xấu?
- 11. Sử dụng toán tử bậc ba để đặt biến số
- 12. Sử dụng toán tử bậc ba với 4 biểu thức
- 13. Tại sao tôi không thể sử dụng toán tử bậc ba với biểu thức này?
- 14. Xử lý lỗi JavaScript: tôi có thể ném lỗi bên trong toán tử bậc ba không?
- 15. Tôi có thể tạo các toán tử bậc ba trong C# không?
- 16. Tại sao tôi không thể gán null cho thập phân với toán tử bậc ba?
- 17. SAS có nội tuyến nếu hàm hoặc toán tử bậc ba không?
- 18. Làm thế nào để thực hiện toán tử điều kiện bậc ba trong MySQL
- 19. Tôi có thể sử dụng hàm __builtin_expect() của GCC với toán tử bậc ba trong C
- 20. Java không suy ra tham số kiểu chung khi sử dụng toán tử bậc ba (`?`)?
- 21. Kết quả của toán tử bậc ba không phải là rvalue
- 22. Chuyển nhượng bên trong các vấn đề toán tử điều kiện bậc ba Perl
- 23. Cách tốt nhất để thay thế toán tử bậc ba bằng Python là gì?
- 24. Sử dụng toán tử bậc ba để khởi tạo biến tham chiếu?
- 25. Làm thế nào để biến nếu, nếu logic vào một toán tử bậc ba?
- 26. Lỗi PostgreSQL: toán tử không tồn tại: name = integer
- 27. Cách tạo toán tử tồn tại kiểu CoffeeScript trong JavaScript?
- 28. Tại sao "xóa [] [] ... multiDimensionalArray;" toán tử trong C++ không tồn tại
- 29. tại sao R không tồn tại lỗi đến trong Android?
- 30. Làm thế nào để xác định toán tử bậc ba trong Scala giữ lại mã thông báo hàng đầu?
Bạn có muốn thứ gì đó mạnh hơn 'ifelse' hoặc chỉ là một hình thức nhỏ gọn hơn không? –
@CarlWitthoft Chủ yếu là hình thức nhỏ gọn hơn; chỉ đơn giản là một cách để lưu văn bản 'if (x> 1) y = 2 else y = 3'. Viết 'y =' một lần có sức hấp dẫn nhất định. – eykanal