0

We can assign the rownames of a data frame by using the <- operator with rownames(df) as below:

df<-data.frame(a=letters[1:5], b=1:5, c=LETTERS[1:5])
df
rownames(df) <- df[,1]
df[,1] <- NULL
df

Above script will convert the first column to rowname, output as below:

df
  a b c
1 a 1 A
2 b 2 B
3 c 3 C
4 d 4 D
5 e 5 E

df
  b c
a 1 A
b 2 B
c 3 C
d 4 D
e 5 E 

Is there a way to use pipe %>% to do it?

I tried df %>% rownames(.) <- .[,1] but failed.
The key issue is cannot use <- between %>%

divibisan
  • 11,659
  • 11
  • 40
  • 58
kittygirl
  • 2,255
  • 5
  • 24
  • 52
  • 1
    I think you want `column_to_rownames` from the *tibble* package - https://tibble.tidyverse.org/reference/rownames.html – thelatemail May 07 '19 at 02:29
  • it's simple function,is there a way not to use additional package? – kittygirl May 07 '19 at 02:34
  • 1
    `%>%` is useful to avoid nesting. It converts `foo(bar(baz(x)))` to `x %>% foo %>% bar %>% baz`. In your example, you start with `rownames(df) <- df[,1]`, which has no nesting. You cannot use `%>%` on the left side of an assignment. – Gregor Thomas May 07 '19 at 02:41
  • 1
    @kittygirl - if you're using the `%>%`, I just assumed you're probably already using dplyr + tibble etc. – thelatemail May 07 '19 at 02:50

3 Answers3

15

While the <- operator looks like something special, when used to replace rownames(), it’s actually a shortcut for the `rownames<-`() function, which you can just call directly in the pipe:

data.frame(a=letters[1:5], b=1:5, c=LETTERS[1:5]) %>%
    `rownames<-`(.[,1])

  a b c
a a 1 A
b b 2 B
c c 3 C
d d 4 D
e e 5 E

This is the function you’re actually always using when you assign rownames:

# When you write this
rownames(df) <- c(1:5)

# What R is actually doing is running this function:
`rownames<-`(df, c(1:5))

You can do the same thing with `colnames<-`() and `names<-`() as well

The backtick character (`) defines something as a symbol, even if it otherwise contains characters that are illegal in a symbol. Enclosing it in backticks tells R that you are running a function called rownames<- and passing in .[,1] as an argument. Without it, R would stop reading the function name when it reaches the < sign, and look for the normal rownames function, which is not what we want here.

Read this question for more detail on the backtick syntax: What do backticks do in R?

divibisan
  • 11,659
  • 11
  • 40
  • 58
2
df <- data.frame(a = letters[1:5], b = 1:5, c = LETTERS[1:5])
df
> df
  a b c
1 a 1 A
2 b 2 B
3 c 3 C
4 d 4 D
5 e 5 E
library(dplyr)
library(tibble)
df1 <- df %>% 
  tibble::column_to_rownames(var = "a")
df1  
> df1
  b c
a 1 A
b 2 B
c 3 C
d 4 D
e 5 E
bbiasi
  • 1,549
  • 2
  • 15
  • 31
1

Without using any additional package, you can achieve the same result by doing

df1 <- data.frame(df[-1], row.names = df[,1])
df1
#  b c
#a 1 A
#b 2 B
#c 3 C
#d 4 D
#e 5 E

and with dplyr you can probably just pull the values from the column to assign to rownames

library(dplyr)
rownames(df) <- df %>% pull(a)
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213