6

Let's say I have this df:

df <- data.frame(a= "a", b = 1, col3 = "c", col4 = "d") %>% print()

When I try to "lengthen" it using this code,

df %>% pivot_longer(1:4, names_to = "test", values_to = "test2")

I get the following error:

Error: Can't combine `a` <factor<127a2>> and `b` <double>.

Why do I get this? Because the first column and first row both have the same value, "a" (I've tried names_repair argument without success)? Or because a and b are different classes? What I don't understand is that I often pivot data of different classes and it always works. Or, is it because I am trying to pivot the actual header (this is what I need to do indeed)?

Any help much appreciated. Desired output:

#a     a
#b     1 
#col3  c
#col4  d
johnjohn
  • 716
  • 2
  • 9
  • 17

2 Answers2

9

You're getting this message because a and b are different classes "see the error message". Define the new column class explicitly by using values_ptypes, this class must be lower than a and b classes in order to cast a and b to it.

tidyr::pivot_longer(df, 1:4, names_to = "test", values_to = "test2", 
                    values_ptypes = list(test2=character()))

# A tibble: 4 x 2
  test  test2
  <chr> <chr>
1 a     a    
2 b     1    
3 col3  c    
4 col4  d    
A. Suliman
  • 12,923
  • 5
  • 24
  • 37
  • 3
    many thanks, A. Suliman, but when I am running your code I get this error: "Error: Can't convert to ." Please disregard my previous comments – johnjohn May 28 '20 at 11:56
  • I am running into the same problem. Do you know any answer to it? – Yannik Suhre Jul 14 '20 at 13:06
  • 1
    @YannikSuhre make sure the input columns have or it's possible to cast into a common type, in this case **a** and **b** may cast to a character type. In short, make sure you're merging columns with the same type, `pivot_longer` will try to protect you from mixing apples with oranges and will send an error when if it fails. See `values_ptypes` definition in `?pivot_longer` documentation. – A. Suliman Jul 14 '20 at 16:25
  • 2
    I found that I had to specify the `values_transform` argument as shown at: https://stackoverflow.com/a/63572366/3362993 – jsta Feb 08 '21 at 15:14
3

This might be more straightforward in base R, where you may simply transpose the data frame. Because it coerces into a matrix just convert back as.data.frame.

as.data.frame(t(df))
#      V1
# a     a
# b     1
# col3  c
# col4  d

Use unname to get cleaner row names.

as.data.frame(unname(t(df)))
#   V1
# 1  a
# 2  1
# 3  c
# 4  d

If you want the names as an extra variable, do this:

data.frame(V1=names(df), V2=unname(t(df)))
#     V1 V2
# 1    a  a
# 2    b  1
# 3 col3  c
# 4 col4  d
jay.sf
  • 60,139
  • 8
  • 53
  • 110