2

I am calculating a table for each row of a data.frame df. I would like to assign these tables as values of a new column of my database (so that each row has one table assigned). But trying to put a table into a data.frame only results in using the first value of the table.

df <- data.frame(values = c("row 1","row 2", "row 3"))

v_row_1 <- c("one", "one", "two", "three", "three")
t_row_1 <- table(v_row_1)

df[1, "tables"] <- t_row_1

Warning message:
In `[<-.data.frame`(`*tmp*`, 1, value = list(values = c(1, 2, 3),  :
provided 2 variables to replace 1 variables

I think that one solution would be to convert my table t into a string object and then assing this object to the cell in my dataframe. But if I use paste(toString(t)) to do this I lose the table names (and I still can't get this thing into a data.frame cell).

My desidered output would roughtly look like:

values             tables
row 1              one 2 three 2 two 1
row 2              ...
row 3              ...

I do not mind if the tables are converted in a linear string as long as they are readable.

Dario Lacan
  • 1,099
  • 1
  • 11
  • 25

1 Answers1

3

(Thanks to @AnandaMahto) You can use

df[1, "tables"] <- toString(sprintf("%s (%d)", names(t), t))

#   values              tables
# 1      1 one 2 three 2 two 1
# 2      2                  NA
# 3      3                  NA

Here's another way to get the string result, borrowed from @Arun's trick for interleaving lists:

df[1, "tables"] <- 
  paste( c(names(t), t)[order(c(seq_along(t), seq_along(t)))], collapse = " " )

Comments.

t is the matrix transpose function, so it might get confusing if you reuse it.

If you want to store the full table object, you can do

df[1,"tables"] <- list(list(t))

The downside is that when viewing df, the names of table elements will not be visible.

Community
  • 1
  • 1
Frank
  • 66,179
  • 8
  • 96
  • 180
  • 1
    This interleaving thing is probably overkill, in light of Ananda's much simpler `sprintf` approach. – Frank Nov 06 '15 at 15:43
  • @AnandaMahto Oh, good catch; it seems it does not. Thanks for adding your answer. I've edited to put it at the top, since it's the best way to go. – Frank Nov 06 '15 at 15:50