9

I've run into the following issue

vec <- c("a11","b21","c31")
df <- data.frame(a = c(0,0,0), b = c(1,1,1), row.names = vec)
df["a",]

returns

df["a",]
    a b
a11 0 1

However,

"a" %in% vec 

and

"a" %in% rownames(df) 

both return False

R is allowing for partial matching of the string when using letter followed by numbers for row names. I have replicated this on R v3.2.2 and R v3.2.1. Even

df[["a",1,exact=T]]

returns 0.

Is there anything I can set such that R does not allow this partial matching?

starball
  • 20,030
  • 7
  • 43
  • 238
Lauren Cote
  • 91
  • 1
  • 2
  • 1
    If you are looking for an option to turn it off, there isn't one. Similar but fairly uneventful http://stackoverflow.com/questions/18033501/warning-when-partial-matching-rownames – Rich Scriven Dec 11 '15 at 22:11

2 Answers2

5

Weird, didn't even realize the partial matching was a thing.

Instead of indexing into the dataframe directly, you could try to identify records that exact match on rowname separately and construct an indexing vector from the result, like so:

> ix <- 'a' == row.names(df)
> df[ix,]
<0 rows> (or 0-length row.names)

or equivalently (but more concisely):

> df['a' == row.names(df),]

Alternatively, if you coerce the object to a data.table it will only return exact matches:

> library(data.table)
> dt <- data.table(df)
> dt[,ix := vec]
> setkey(dt, ix)

> dt['a']
    a  b ix
1: NA NA  a

> dt['a11']
   a b  ix
1: 0 1 a11
David Marx
  • 8,172
  • 3
  • 45
  • 66
2

Why not try:

df[grep(pattern = "a", x = rownames(df)),]

Which would return:

> df[grep(pattern = "a", x = rownames(df)),]
    a b
a11 0 1

Making use of grep would provide you with addittional flexibility, for example if you want to match row names that would have a only:

> df[grep(pattern = "^a$", x = rownames(df)),]
[1] a b
<0 rows> (or 0-length row.names)
Konrad
  • 17,740
  • 16
  • 106
  • 167