Messy and inefficient Base R solution (should do exactly what you are after):
get_percentile_value <- function(vec_w_idx){
# Store argument as string: val => string scalar
val <- deparse(substitute(vec_w_idx))
# Extract the index from the argument: idx => integer scalar
idx <- as.integer(gsub("(.*[[])(\\d+)[]]", "\\2", val))
# Pull vector referenced in argument from Global Environment:
# vec => numeric vector
vec <- eval(parse(text = gsub("(^\\w+)\\[.*", "\\1", val)))
# Calculate the percentile rank of each value in the vector:
# pc_rnk => data.frame
pc_rnk <- data.frame(srt_vec = sort(vec), pc_rnk = seq_along(vec)/length(vec))
# Lookup the percentile rank and store it as a vector: res => data.frame
res <- data.frame(vec = vec, pc_rnk = pc_rnk$pc_rnk[match(vec, pc_rnk$srt_vec)])
# Return the percentile rank of the value at given index:
# double scalar => .GlobalEnv()
return(res$pc_rnk[idx])
}
# Apply function: double scalar => stdout (console)
get_percentile_value(a[14])
Or if the output must match exactly what you requested:
# Function to take a vector (with index provided), and return
# a percentile rank: get_percentile_value => function()
get_percentile_value <- function(vec_w_idx){
# Store argument as string: val => string scalar
val <- deparse(substitute(vec_w_idx))
# Extract the index from the argument: idx => integer scalar
idx <- as.integer(gsub("(.*[[])(\\d+)[]]", "\\2", val))
# Pull vector referenced in argument from Global Environment:
# vec => numeric vector
vec <- eval(parse(text = gsub("(^\\w+)\\[.*", "\\1", val)))
# Calculate the percentile rank of each value in the vector:
# pc_rnk => data.frame
pc_rnk <- data.frame(srt_vec = sort(vec), pc_rnk = seq_along(vec)/length(vec))
# Lookup the percentile rank and store it as a vector: res => data.frame
res <- data.frame(vec = vec, pc_rnk = pc_rnk$pc_rnk[match(vec, pc_rnk$srt_vec)])
# Return the percentile rank of the value at given index:
# double scalar => .GlobalEnv()
return(paste0(round(res$pc_rnk[idx] * 100, 4), "%"))
}