Filter and Find
Part of the Logic & Flow section of Coddy's R journey. Lesson 34 of 64.
Filter(f, x) keeps the elements for which the predicate f returns TRUE, in their original order:
nums <- c(12, 5, 30, 7, 18)
print(Filter(function(n) n > 10, nums))
print(Filter(function(n) n %% 2 == 1, nums))Output:
[1] 12 30 18
[1] 5 7For a vector, logical indexing does the same job: nums[nums > 10]. Filter() is useful when the test is not vectorized, such as a check that splits a string or calls if:
words <- c("level", "tea", "noon", "cat")
is_palindrome <- function(w) w == paste(rev(strsplit(w, "")[[1]]), collapse = "")
print(Filter(is_palindrome, words))Output:
[1] "level" "noon" Find(f, x) returns the first element that passes, and Position(f, x) its position. When nothing passes, both return NULL or NA:
nums <- c(3, 8, 15, 4)
print(Find(function(n) n > 5, nums))
print(Position(function(n) n > 5, nums))
print(is.null(Find(function(n) n > 100, nums)))Output:
[1] 8
[1] 2
[1] TRUEFilter() also works on lists, for example to keep the records that meet a condition:
people <- list(list(name = "Ada", age = 36), list(name = "Tim", age = 12))
adults <- Filter(function(p) p$age >= 18, people)
print(length(adults))
print(adults[[1]]$name)Output:
[1] 1
[1] "Ada"Challenge
EasyComplete valid_emails(emails). An address is valid when it contains exactly one @, has no spaces, and has at least one character before and after the @. Return Valid: followed by the number of valid addresses, then one line per valid address in order.
Count the @ characters with nchar(e) - nchar(gsub("@", "", e, fixed = TRUE)).
The supplied code reads the addresses as a comma-separated line and prints each returned line.
Try it yourself
valid_emails <- function(emails) {
# Write your code here
"Valid: 0"
}
# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
cat(valid_emails(strsplit(input[1], ",")[[1]]), sep = "\n")
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
Substrings with substr()Formatting with sprintf()Splitting and JoiningSearching StringsReplacing TextRecap - Username Builder4Matrices
Creating MatricesIndexing MatricesRow and Column SummariesMatrix ArithmeticRecap - Seating Chart2Key-Value Lookups
Named Vector LookupsChecking KeysAdding and Removing KeysLooping Over NamesRecap - Stock Desk3Sets and Counting
Unique ValuesSet OperationsMembership TestsCounting with table()Recap - Event Guests6Functions as Values
Anonymous FunctionsPassing FunctionsReturning FunctionsClosures with StateRecap - Discount Rules9Data Frames
Creating Data FramesColumns and RowsFiltering RowsAdding and SortingRecap - Sales Report12Project - Expense Tracker
Recording ExpensesTotal SpendingPractice on your own: Online R compiler