Sheila
Sheila

Reputation: 2596

Error when unlisting columns in a data frame

Suppose I have a data frame called DF:

options(stringsAsFactors = F)

letters <- list("A", "B", "C", "D")
numbers <- list(list(1,2), 1, 1, 2)
score <- list(.44, .54, .21, .102)

DF <- data.frame(cbind(letters, numbers, score))

Note that all columns in the data frame are of class "list".

Also, take a look at the structure: DF$numbers[1] is also a list

I'm trying to UNLIST each column.

 DF$letters <- unlist(DF$letters)
 DF$score <- unlist(DF$score)
 DF$numbers <- unlist(DF$numbers)

However, because, DF$numbers[1] is also a list, I'm thrown back this error:

 Error in `$<-.data.frame`(`*tmp*`, numbers, value = c(1, 2, 1, 1, 2)) : 
   replacement has 5 rows, data has 4

Is there a way that I can unlist the whole column, and keep the values cells like DF$numbers[1] as a character vector like c(1,2) or 1,2?

Ideally I would like DF to look something like this, where the individual values in the number column are still of type int:

 letters   numbers   score
  A         1,2       .44
  B         1         .54
  C         1         .21
  D         2         .102

The goal is to then write the data frame to a csv file.

Upvotes: 0

Views: 1172

Answers (2)

akuiper
akuiper

Reputation: 214957

You can apply unlist to each individual element of the column numbers instead of the whole column:

DF$numbers <- lapply(DF$numbers, unlist)

DF
#  letters numbers value
#1       A    1, 2 0.440
#2       B       1 0.540
#3       C       1 0.210
#4       D       2 0.102

DF$numbers[1]
#[[1]]
#[1] 1 2

Or paste the elements as a single string if you want an atomic vector column:

DF$numbers <- sapply(DF$numbers, toString)
DF
#  letters numbers value
#1       A    1, 2  0.44
#2       B       1  0.54
#3       C       1  0.21
#4       D       2 0.102

DF$numbers[1]
#[1] "1, 2"

class(DF$numbers)
# [1] "character"

Upvotes: 1

Lamia
Lamia

Reputation: 3875

You can do:

DF$letters <- unlist(DF$letters)
DF$value <- unlist(DF$value)
DF$numbers <- unlist(as.character(DF$numbers))

This returns:

DF
  letters numbers value
1       A c(1, 2) 0.440
2       B       1 0.540
3       C       1 0.210
4       D       2 0.102

Upvotes: 0

Related Questions