Reputation: 609
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
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