13

Not sure if I used the correct english words in the subject to describe what I need.

See this example

df <- data.frame(a=sample(1:10), b=sample(1:10))
df
    a  b
1   2  9
2   5  8
3  10  1
4   3  7
5   8  4
6   6 10
7   9  5
8   7  6
9   1  3
10  4  2

I want to take b column at put it below a as 10 new rows.

    a
1   2
2   5
3  10
4   3
5   8
6   6
7   9
8   7
9   1
10  4
11  9
12  8
13  1
14  7
15  4
16 10
17  5
18  6
19  3
20  2

I found examples with rbind but couldn't find out how to use it in my situation.

buhtz
  • 10,774
  • 18
  • 76
  • 149
  • 3
    `rbind` fails because it is assuming the arguments you are passing in are rows, thus a 2x10 result. You would use `c()` for an end to end or 20x1 result – Nate Nov 27 '16 at 16:35

6 Answers6

16

We can use unlist to create a vector and then wrap it with data.frame to create a new dataset.

d1 <- data.frame(a=unlist(df, use.names = FALSE))
d1
#    a
#1   2
#2   5
#3  10
#4   3
#5   8
#6   6
#7   9
#8   7
#9   1
#10  4
#11  9
#12  8
#13  1
#14  7
#15  4
#16 10
#17  5
#18  6
#19  3
#20  2
akrun
  • 874,273
  • 37
  • 540
  • 662
10

You could also do :

df2 <- data.frame(a = c(df[,"a"], df[,"b"]))
User2321
  • 2,952
  • 23
  • 46
  • how do i retain the names/text. This one converts my text to numbers? – Aditya Hariharan Jan 29 '18 at 09:54
  • Hi! Could you be a bit more specific? The names of the columns you mean? If yes, well the whole point was to have a new column which combines them all. It will indeed convert the numbers if one of the two columns is not numeric. R tries to find the common denominator and will convert everything to it (most likely in your case character). – User2321 Jan 29 '18 at 11:45
  • well in my case both columns are email addresses, so they do have numbers and special characters. Is there any way to specify that I want only characters? – Aditya Hariharan Jan 30 '18 at 03:19
  • Yes by using regular expressions, but this is a totally different question. Have a look here perhaps https://stackoverflow.com/questions/25076575/how-to-extract-expression-matching-an-email-address-in-a-text-file-using-r-or-co or just post a new question :) – User2321 Jan 31 '18 at 14:27
6

You can use pivot_longer() from tidyr package.

library(dplyr)
set.seed(1)
df <- data.frame(a=sample(1:10), b=sample(1:10))
pivot_longer(df, a:b)


# A tibble: 20 x 2
   name  value
   <chr> <int>
 1 a         3
 2 b         3
 3 a         4
 4 b         2
 5 a         5
 6 b         6
 7 a         7
 8 b        10
 9 a         2
10 b         5
11 a         8
12 b         7
13 a         9
14 b         8
15 a         6
16 b         4
17 a        10
18 b         1
19 a         1
20 b         9
Tiago Olivoto
  • 61
  • 1
  • 2
2

You can select a and bind it to b in the following way:

df <- data.frame(a=sample(1:10), b=sample(1:10))
df %>% 
  select(a) %>% 
  bind_rows(
    df %>% 
      transmute(a = b)
  )
Werner
  • 14,324
  • 7
  • 55
  • 77
1

You can also use both tidyr and dplyr to end with a new data.frame.

library(tidyr)
library(dplyr)
set.seed(1)
df <- data.frame(a=sample(1:10), b=sample(11:20), c=sample(21:30))
head(df)

df2 <- pivot_longer(df, a:c, names_to = "letter", values_to = "d")
df3 <- data.frame(arrange(df2, letter))
head(df3); str(df3)

Now all three columns are combined into a 2 column data frame with 30 rows.

Be cautious with creating columns that are longer than the original data.frame, as they will repeat other columns to make the entire data.frame have the correct number of rows. This might be advantageous when repeating the subjects over and over, but could be problematic in others circumstances.

df4 <- pivot_longer(df, c(a,c), names_to = "letter", values_to = "d")
df5 <- data.frame(arrange(df4, letter))
head(df5); str(df5)
df5

Notice R duplicated column 'b' in order to make it as long as the other columns (20 char)

Gregg-G
  • 45
  • 4
1

You can just combine the variables into one.

df <- data.frame(a=sample(1:10), b=sample(1:10))
df2 <- data.frame(a = c(df$a, df$b))
buhtz
  • 10,774
  • 18
  • 76
  • 149
jagubat
  • 11
  • 2