How do I locate a row number within a dataframe of a known value?

Suppose


helloworld <- c(rep(0,49681))

and max(helloworld) and min(helloworld) produced 1 and 1.37858e-12 respectively.

I tried to call(locate) the row numbers using [which] function:

which(helloworld=1.37858e-12)
Error in which(helloworld= 1.37858e-12) : unused argument (helloworld= 1.37858e-12)

which is a base function in R. What am I doing wrong? any alternatives?

Use == for comparison: which(helloworld==1), which(helloworld==min(helloworld)), etc.

2 Likes

Hi @joels, thanks for your answer. Just a doubt. Is there any reason why it wont for which(helloworld==1.37858e-12). The output shows as integer(0). But when I use which(helloworld==min(helloworld)) then it works fine

I was just working up some code to address this. The issue is machine precision. == will only return TRUE if the two values are exactly equal. But there might not be any values in helloworld that are exactly equal to 1.37858e-12.

R by default prints only the first 7 decimal places in the console, even though numbers are stored with much higher precision. If you type options(digits=20) into the console (so that 20 decimal places will be printed in the console) and then type min(helloworld), you'll probably see that one or more of the additional decimal places are not zero, and therefore there is no element of helloworld that is exactly equal to 1.37858e-12.

A way around this is to test whether two values are nearly equal to within some tolerance. You can write your own function for this, but R has the built-in all.equal function. Here are some examples:

library(purrr)

set.seed(2)
y = rnorm(10)     

options(digits=20)
target1 = y[8]
target2 = round(y[8], 8)

c(target1, target2)
#> [1] -0.23969802417184010723 -0.23969802000000001163

target1 == target2
#> [1] FALSE
all.equal(target1, target2) # Default tolerance
#> [1] "Mean relative difference: 1.7404566057710392839e-08"
all.equal(target1, target2, tolerance=1e-7)
#> [1] TRUE

y == target1
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
y == target2
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

which(y == target1)
#> [1] 8
which(y == target2)
#> integer(0)

target3 = round(y[8], 15)

map_lgl(y, ~as.logical(all.equal(.x, target1)))
#>  [1]   NA   NA   NA   NA   NA   NA   NA TRUE   NA   NA
map_lgl(y, ~as.logical(all.equal(.x, target2)))
#>  [1] NA NA NA NA NA NA NA NA NA NA
map_lgl(y, ~as.logical(all.equal(.x, target3)))
#>  [1]   NA   NA   NA   NA   NA   NA   NA TRUE   NA   NA

which(map_lgl(y, ~as.logical(all.equal(.x, target1))))
#> [1] 8
which(map_lgl(y, ~as.logical(all.equal(.x, target2))))
#> integer(0)
which(map_lgl(y, ~as.logical(all.equal(.x, target3))))
#> [1] 8

y[which(map_lgl(y, ~as.logical(all.equal(.x, target1))))]
#> [1] -0.23969802417184010723
y[which(map_lgl(y, ~as.logical(all.equal(.x, target2))))]
#> numeric(0)
y[which(map_lgl(y, ~as.logical(all.equal(.x, target3))))]
#> [1] -0.23969802417184010723

Created on 2018-11-28 by the reprex package (v0.2.1)

3 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.