Jemus42
Jemus42

Reputation: 719

Add vector as data.frame element as is

I have a data.frame consisting of (initially) one observation. From the original data, I have a list (more specifically, a character vector) which should be appended to the data.frame as a new column and contained in a single element.

Specifically, I have this data.frame:

> str(stats.df)
'data.frame':   1 obs. of  174 variables:
 $ stat.mineBlock.minecraft.furnace              : num 1
 $ stat.useItem.minecraft.fence_gate             : num 1
 $ stat.useItem.minecraft.stone_brick_stairs     : num 3
 $ stat.killEntity.Sheep                         : num 20
 $ stat.useItem.minecraft.cobblestone            : num 18  

And I want to add the following:

> str(stats.list$achievement.exploreAllBiomes$progress)
  chr [1:6] "Desert" "Extreme Hills" "Ocean" "Extreme Hills Edge" "River" "Hell"

So that

 > stats.df$achievement.exploreAllBiomes.progress
  [1] "Desert"             "Extreme Hills"      "Ocean"              "Extreme Hills Edge"
  [5] "River"              "Hell" 

Because stats.list$achievement.exploreAllBiomes contains to elements: value, which is a numeric, and progress, which is a character vector. I want my stats.df to contain each of those as separate columns.

My problem is that the data.frame is expanded with additional rows for each element of the character vector, so that each row of the data.frame is identical and only varies in the achievement.exploreAllBiomes.progress field, where each row contains one element of said vector.

I have tried the following 3 three things, with and without using I():

 stats.df$achievement.exploreAllBiomes.progress        <- I(stats.list$achievement.exploreAllBiomes$progress)
 stats.df$achievement.exploreAllBiomes.progress[1]     <- I(stats.list$achievement.exploreAllBiomes$progress)
 cbind(stats.df, achievement.exploreAllBiomes.progress = I(stats.list$achievement.exploreAllBiomes$progress))

Receiving either

 Error in `$<-.data.frame`(`*tmp*`, "achievement.exploreAllBiomes.progress",  : 
 replacement has 6 rows, data has 1

or the duplicate row variant. I assumed I()would do the trick, but it only seems to work when constructing the data.frame from scratch, so I tried constructing stats.df with that in mind:

stats.df <- data.frame(stats.list[names(stats.list) != "achievement.exploreAllBiomes"],
                     achievement.exploreAllBiomes.value    = stats.list$achievement.exploreAllBiomes$value,
                     achievement.exploreAllBiomes.progress =  I(stats.list$achievement.exploreAllBiomes$progress))

But again this produced the duplicate rows. I know that it is possible for an element in a data.frame to contain a vector or list, so I assume there has to be a fairly easy way to achieve this which I'm probably just not seeing.

Upvotes: 3

Views: 3327

Answers (1)

tonytonov
tonytonov

Reputation: 25608

Here's how you can do that:

stats.df <- data.frame(stat.mineBlock.minecraft.furnace = 3, 
                       stat.useItem.minecraft.fence_gate = 5)

stats.list <- c("Desert", "Extreme Hills", "Ocean", "Extreme Hills Edge", "River", "Hell")

stats.df$achievement.exploreAllBiomes.progress <- I(list(stats.list))
stats.df$ach[[1]]

#[1] "Desert"             "Extreme Hills"      "Ocean"             
#[4] "Extreme Hills Edge" "River"              "Hell" 

str(stats.df)
#'data.frame':  1 obs. of  3 variables:
# $ stat.mineBlock.minecraft.furnace     : num 3
# $ stat.useItem.minecraft.fence_gate    : num 5
# $ achievement.exploreAllBiomes.progress:List of 1
#  ..$ : chr  "Desert" "Extreme Hills" "Ocean" "Extreme Hills Edge" ...
#  ..- attr(*, "class")= chr "AsIs"

Upvotes: 3

Related Questions