bli bli - 14 days ago 11
R Question

"attempt to extract more than one element" from an R data.frame-like object

I have an object (here named

rld
) which looks a bit like a data.frame in that it has columns that can be accessed using
$
or
[[]]
.

I have a vector (here named
groups
) containing names of some of its columns (here 3 column names).

I generate strings based on combinations of elements in the columns as follows:

paste(rld[[groups[1]]], rld[[groups[2]]], rld[[groups[3]]], sep="-")


I would like to generalize this so that I don't need to know how many elements are in
groups
.

The following attempt fails:

> paste(rld[[groups]], collapse="-")
Error in normalizeDoubleBracketSubscript(i, x, exact = exact, error.if.nomatch = FALSE) :
attempt to extract more than one element


How to do this in an elegant way ?

Edit: Here is how I would do in functional-style with a python dictionary:



map("-".join, zip(*map(rld.get, groups)))


Is there a similar column-getter operator in R ?

Answer

We may use either of the following:

do.call(function (...) paste(..., sep = "-"), rld[groups])
do.call(paste, c(rld[groups], sep = "-"))

We can consider a small, reproducible example:

rld <- mtcars[1:5, ]
groups <- names(mtcars)[c(1,3,5,6,8)]
do.call(paste, c(rld[groups], sep = "-"))
#[1] "21-160-3.9-2.62-0"     "21-160-3.9-2.875-0"    "22.8-108-3.85-2.32-1" 
#[4] "21.4-258-3.08-3.215-1" "18.7-360-3.15-3.44-0"

Note, it is your responsibility to ensure all(groups %in% names(rld)) is TRUE, otherwise you get "subscript out of bound" or "undefined column selected" error.


(I am copying your comment as a follow-up)

It seems the methods you propose don't work directly on my object. However, the package I'm using provides a colData function that makes something more similar to a data.frame:

class(colData(rld))
# [1] "DataFrame", attr(,"package")
# [1] "S4Vectors".

do.call(function (...) paste(..., sep = "-"), colData(rld)[groups]) works, but do.call(paste, c(colData(rld)[groups], sep = "-")) fails with an error message I fail to understand (as too often with R...).