Carmen Sandoval
Carmen Sandoval

Reputation: 2356

Convert a quosure with dashes to a string?

When I do:

> quo(DLX6-AS1) 

The output is:

<quosure>
expr: ^DLX6 - AS1
env:  global

Which inserts spaces around the dash.

When I try to convert that to a string, I get either:

quo(DLX6-AS1) %>% quo_name

"DLX6 - AS1"

or

quo(DLX6-AS1) %>% rlang::quo_name

or

quo(`DLX6-AS1`) %>% rlang::quo_name

Error: Can't convert a call to a string

How can I make it possible to use strings with dashes in my function? The function takes in a gene name and looks up that row in a dataframe, but some of the genes are concatenated by a dash:

geneFn <- function(exp.df = seurat.object@data, gene = SOX2) {

    gene <- enquo(gene)

    exp.df <- exp.df[as_name(gene), ] 

}

> geneFn(DLX6-AS1)

Thanks!

This has been asked before here: https://github.com/r-lib/rlang/issues/770 , but it doesn't answer how to actually do this.

Upvotes: 4

Views: 401

Answers (3)

moodymudskipper
moodymudskipper

Reputation: 47320

What about:

geneFn <- function(exp.df = seurat.object@data, gene = SOX2) {
    gene <- sub(" - ","-", deparse(enexpr(gene)))
    exp.df <- exp.df[gene, ] 
}

Upvotes: 0

Lionel Henry
Lionel Henry

Reputation: 6803

What version of rlang do you have? For me this works:

quo(`DLX6-AS1`) %>% quo_name()
#> [1] "DLX6-AS1"

You do need to use backticks when column names have special characters, otherwise they are interpreted as code.

Note that it is recommended to use either as_name() or as_label() instead of quo_name(), the latter was a misleading misnomer and might be deprecated in the future.

Upvotes: 2

aosmith
aosmith

Reputation: 36086

One option would be to stick with bare row names but wrap names that aren't syntactically valid (like names with dashes) in backticks. This could be confusing if someone else is supposed to use this function.

Here's a small, reproducible example:

library(rlang)

dat = data.frame(x1 = letters[1:2],
                 x2 = LETTERS[1:2])
row.names(dat) = c("DLX6-AS1", "other")

geneFn <- function(exp.df = dat, gene = other) {

    gene <- enquo(gene)

    exp.df[as_name(gene), ] 

}

geneFn(gene = other)
#       x1 x2
# other  b  B
geneFn(gene = `DLX6-AS1`)
#          x1 x2
# DLX6-AS1  a  A

If you have many names like this, it may be simpler to pass quoted names instead of bare names. This also simplifies the function a bit since you don't need tidyeval.

geneFn2 <- function(exp.df = dat, gene = "other") {

    exp.df[gene, ] 

}

geneFn2(gene = "other")
#       x1 x2
# other  b  B
geneFn2(gene = "DLX6-AS1")
#          x1 x2
# DLX6-AS1  a  A

Another option is to make syntactically valid names row names. The make.names() function can help with this.

make.names( row.names(dat) )
[1] "DLX6.AS1" "other"  

Then you could assign these new row names to replace the old and go ahead with your original function with the new names.

row.names(dat) = make.names( row.names(dat) )

Upvotes: 1

Related Questions