Annemarie
Annemarie

Reputation: 609

R delete rows of list element and keep rownames

I have a dataframe with empty cells that I split into a list:

df <- data.frame(c("q","w","","r","t","y"),c("a","b","","d","e","f"),c("x","c","v","b","","m"))
colnames(df) <- c("qwerty","abc","bnm")
rownames(df) <- c("1a","1b","1c","1d","1e","1f")
list <- lapply(df, as.data.frame)
for(i in 1:length(list)){  rownames(list[[i]]) <- rownames(df) }

However, when I remove the empty rows from one of the list's elements, rownames are deleted for that element:

list[[1]] <- list[[1]][list[[1]] != "",]
rownames(list[[1]])
NULL

How can I prevent this from happening?

Upvotes: 3

Views: 2219

Answers (1)

David Arenburg
David Arenburg

Reputation: 92292

The row names were "deleted" because you converted your data frame to a vector (which don't have row names by definition).

This is happening when you are trying to subset a data.frame which contains only one column. In order to prevent this, use drop = FALSE as in:

lapply(list, function(x) x[x != "",, drop = FALSE])
# $qwerty
#     X[[1L]]
# 1a       q
# 1b       w
# 1d       r
# 1e       t
# 1f       y
# 
# $abc
#    X[[2L]]
# 1a       a
# 1b       b
# 1d       d
# 1e       e
# 1f       f
# 
# $bnm
#    X[[3L]]
# 1a       x
# 1b       c
# 1c       v
# 1d       b
# 1f       m

In order to illustrate this, consider the following example

df <- data.frame(A = c("a", "", "b"))
(subdf <- df[df$A != "", ])
# [1] a b
# Levels:  a b
class(subdf)
# [1] "factor"
rownames(subdf)
# NULL

For further information see ?"[.data.frame"

drop

logical. If TRUE the result is coerced to the lowest possible dimension. The default is to drop if only one column is left, but not to drop if only one row is left.

Upvotes: 6

Related Questions