27

My data looks like this:

round <- c(rep("A", 3), rep("B", 3))
experiment <- rep(c("V1", "V2", "V3"), 2)
results <- rnorm(mean = 10, n = 6)

df <- data.frame(round, experiment, results)

> df
  round experiment   results
1     A         V1  9.782025
2     A         V2  8.973996
3     A         V3  9.271109
4     B         V1  9.374961
5     B         V2  8.313307
6     B         V3 10.837787

I have a different dataset that will be merged with this one where each combo of round and experiment is a unique row value, ie, "A_V1". So what I really want is a variable name that concatenates the two columns together. However, this is tougher to do in dplyr than I expected. I tried:

name_mix <- paste0(df$round, "_", df$experiment)
new_df <- df %>%
  mutate(name = name_mix) %>%
  select(name, results)

But I got the error, Column name must be length 1 (the group size), not 6. I also tried the simple base-R approach of cbind(df, name_mix) but received a similar error telling me that df and name_mix were of different sizes. What am I doing wrong?

micstr
  • 5,080
  • 8
  • 48
  • 76
mmyoung77
  • 1,343
  • 3
  • 14
  • 22
  • 1
    Use `new_df <- df %>% mutate(name=paste0(round, "_", experiment))`. Though if i copy/paste your code i cannot reproduce that error. Are you sure there's no typo somewhere? – MrFlick Jun 13 '18 at 20:18
  • @MrFlick I don't get an error message at all, so a little confused... Maybe update `dplyr`? – tyluRp Jun 13 '18 at 20:20
  • checked my code (from IRL, not the example above) like crazy for typos, so I don't think it's that. Using `unite`, as below, seems to work. – mmyoung77 Jun 13 '18 at 20:23

4 Answers4

49

You can use the unite function from tidyr

require(tidyverse)

df %>% 
  unite(round_experiment, c("round", "experiment"))

  round_experiment   results
1             A_V1  8.797624
2             A_V2  9.721078
3             A_V3 10.519000
4             B_V1  9.714066
5             B_V2  9.952211
6             B_V3  9.642900
DJV
  • 4,743
  • 3
  • 19
  • 34
12

This should do the trick if you are looking for a new variable

library(tidyverse)

round <- c(rep("A", 3), rep("B", 3))
experiment <- rep(c("V1", "V2", "V3"), 2)
results <- rnorm(mean = 10, n = 6)

df <- data.frame(round, experiment, results)
df

df <- df %>% mutate(
  name = paste(round, experiment, sep = "_")
)
6

You could also try this:

library(tidyr)
library(dplyr)
df = df %>% 
   unite(combined, round, experiment, sep = "_", remove = FALSE)

The output will be:

combined round experiment   results
 A_V1     A         V1      10.152329
 A_V2     A         V2      10.863128
 A_V3     A         V3      10.975773
 B_V1     B         V1       9.964696
 B_V2     B         V2       9.876675
 B_V3     B         V3       9.252936

This will retain your original columns.

Sandy
  • 1,100
  • 10
  • 18
3

Another solution could be to use the stri_join function in stringi package.

library(stringi)
df$new = stri_join(df$round,df$experiment,sep="_")
MSW Data
  • 441
  • 3
  • 8