Kiểm tra nếu một vectơ chứa một phần tử đã cho


518

Làm thế nào để kiểm tra nếu một vectơ chứa một giá trị nhất định?


38
đôi khi tôi tự hỏi tại sao R chỉ không sử dụng từ có chứa để làm cho người dùng dễ dàng hơn
greg121

12
xem xét rằng "trong" được chứa trong "conta (in) s"; Tôi cho rằng "trong" là một ứng cử viên ngắn gọn đáng kể trong bối cảnh này
hedgedandlevered 11/03/2016

1
Có lẽ với việc bổ sung sườn %- đó là. Từ innày là một từ dành riêng trong R sử dụng trong xây dựng vòng lặp for.
IRTFM

@ greg121 dplyr đã có chức năng chứa , nhưng nó được sử dụng cho mục đích khác: để chọn một cột trong khung dữ liệu. Ví dụ select(iris, contains("etal")).
Paul Rougieux

Có cách nào ngắn gọn để làm điều đó cho các số có giá trị thực với độ chính xác nhất định không?
mlt

Câu trả lời:


500

Cả hai hàm match()(trả về lần xuất hiện đầu tiên) và %in%(trả về hàm Boolean) đều được thiết kế cho việc này.

v <- c('a','b','c','e')

'b' %in% v
## returns TRUE

match('b',v)
## returns the first location of 'b', in this case: 2

Điều gì về việc có được tất cả sự xuất hiện, không chỉ là lần đầu tiên?
Số liệu thống kê

Có lẽ tôi đến muộn một chút. which(v, 'b'). Tâm trí thứ tự của các cuộc tranh luận.
Niklas Mertsch

Bạn which(v, 'b')đưa cho tôi một thông báo lỗi:> Lỗi trong đó (v, 'b'): đối số với 'which' không logic
Capt.Krusty

176

is.element() làm cho mã dễ đọc hơn và giống hệt với mã %in%

v <- c('a','b','c','e')

is.element('b', v)
'b' %in% v
## both return TRUE

is.element('f', v)
'f' %in% v
## both return FALSE

subv <- c('a', 'f')
subv %in% v
## returns a vector TRUE FALSE
is.element(subv, v)
## returns a vector TRUE FALSE

6
Tôi biết các tài liệu nói is.element(x, y) is identical to x %in% y. Nhưng, tôi không biết tại sao, is.elementshoạt động khi trộn số nguyên và số và %in%không
pomber 28/12/14

@pomber: Bạn có thể cho một ví dụ về điều này?
discipulus

@pomber có cố định không?
vasili111

2
Khả năng đọc vượt trội is.element()so với %in%chủ quan. Một trường hợp có thể được thực hiện rằng một toán tử infix dễ đọc hơn bởi vì nó loại bỏ sự mơ hồ theo thứ tự các đối số. apple in fruitcó ý nghĩa, fruit in applekhông. is.element(apple, fruit)hoặc is.element(fruit, apple)cả hai có thể đúng tùy thuộc vào việc thực hiện is.elementchức năng.
rileymcdowell

70

Tôi sẽ nhóm các tùy chọn dựa trên đầu ra. Giả sử các vectơ sau cho tất cả các ví dụ.

v <- c('z', 'a','b','a','e')

Để kiểm tra sự hiện diện:

%trong%

> 'a' %in% v
[1] TRUE

bất kì()

> any('a'==v)
[1] TRUE

is.element ()

> is.element('a', v)
[1] TRUE

Đối với việc tìm kiếm sự xuất hiện đầu tiên:

trận đấu()

> match('a', v)
[1] 2

Để tìm tất cả các lần xuất hiện dưới dạng vectơ của các chỉ số:

mà ()

> which('a' == v)
[1] 2 4

Để tìm tất cả các lần xuất hiện dưới dạng vector logic :

==

> 'a' == v
[1] FALSE  TRUE FALSE  TRUE FALSE

Chỉnh sửa: Xóa grep ()grepl () khỏi danh sách vì lý do được đề cập trong các nhận xét


6
Như đã nhận xét ở đâyở đây , không sử dụng grep()hoặc biểu thức chính quy để tìm kết quả khớp chính xác.
Uwe

69

Hàm any () làm cho mã có thể đọc được

> w <- c(1,2,3)
> any(w==1)
[1] TRUE

> v <- c('a','b','c')
> any(v=='b')
[1] TRUE

> any(v=='f')
[1] FALSE

9
Hãy nhận biết điều này hành xử khác với %in%: any(1==NA)trả về NA, nơi 1 %in% NAtrả về FALSE.

@ user3603486: any(1==NA, na.rm=TRUE)trả lại FALSE.
AkselA

36

Bạn có thể sử dụng %in%toán tử:

vec <- c(1, 2, 3, 4, 5)
1 %in% vec # true
10 %in% vec # false

19

Ngoài ra để tìm vị trí của phần tử "mà" có thể được sử dụng như

pop <- c(3,4,5,7,13)

which(pop==13)

và để tìm các phần tử không có trong vectơ đích, người ta có thể làm điều này:

pop <- c(1,2,4,6,10)

Tset <- c(2,10,7)   # Target set

pop[which(!(pop%in%Tset))]

whichđôi khi thực sự thích hợp hơn vì nó cung cấp cho bạn tất cả các vị trí phù hợp (dưới dạng một mảng), không giống như match. Mặc dù đây có lẽ không phải là những gì OP yêu cầu, không giống như stackoverflow.com/questions/1169388/NH
Fizz

2
Tại sao phải bận tâm whichnếu bạn chỉ muốn tìm các yếu tố không trong Tset? Bạn chỉ có thể lập chỉ mục poptrực tiếp; pop[!pop%in%Tset]
Houshalter

13

Tôi thực sự thích grep () và grepl () cho mục đích này.

grep () trả về một vectơ số nguyên, cho biết vị trí khớp.

yo <- c("a", "a", "b", "b", "c", "c")

grep("b", yo)
[1] 3 4

grepl () trả về một vectơ logic, với "TRUE" tại vị trí khớp.

yo <- c("a", "a", "b", "b", "c", "c")

grepl("b", yo)
[1] FALSE FALSE  TRUE  TRUE FALSE FALSE

Các chức năng này là trường hợp nhạy cảm.


10
Theo mặc định, greplấy một biểu thức chính quy làm thành phần đầu tiên của nó, do đó, để thực hiện khớp chính xác cho "b", sử dụng ^e$hoặc thêm , fixed=TRUE).
rebierpost

10
Không sử dụng regex cho các trận đấu chính xác. Điều này là nguy hiểm và có thể có kết quả bất ngờ
David Arenburg

9
Vâng, đây là một ý tưởng tồi tệ, không tốt, rất xấu - không hiệu quả và được đảm bảo để phá vỡ. Ví dụ: myvar <- 'blah'; grepl('b', myvar, fixed=TRUE)sẽ trở lại TRUEmặc dù 'b' không ở trong myvar.
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.