Joko
Joko

Reputation: 2589

Convert a row of a data frame to vector

I want to create a vector out of a row of a data frame. But I don't want to have to row and column names. I tried several things... but had no luck.

This is my data frame:

> df <- data.frame(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))
> df
  a b   c
1 1 2 2.6
2 2 6 8.2
3 4 2 7.5
4 2 1 3.0

I tried:

> newV <- as.vector(df[1,])
> newV
  a b   c
1 1 2 2.6

But I really want something looking like this:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6

Upvotes: 162

Views: 225770

Answers (7)

streamline
streamline

Reputation: 135

If you are looking for a solution that uses dplyr.

require(dplyr)

df <- tibble(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))

df %>% 
  # create a set of duplicated columns for your source columns
  mutate(across(c(a, b, c),
                ~ .,
                .names = "duplicated_{.col}")) %>% 

  # nest the new/duplicated columns, usable in most cases
  nest(nested_data = matches("duplicated_")) %>% 

  # or use only the first row of each new data frame (nested)
  # rowwise is important
  rowwise %>% 
  mutate(nested_data = list(slice_head(nested_data, n = 1) %>% as.numeric(.))) 

Note that:

  • unnesting after the steps above will give you a long/melted data frame;
  • there is an intrinsic reason why nesting does not keep the original/source columns (e.g., to avoid potential conflicts in the data further down the road). So, duplicating the columns may be a solution, or maybe more of a fix, and should be used on a case-by-case basis;
  • this gives you a numeric vector corresponding to selected data in each of the rows, as per your use case.

Upvotes: 0

Ben Bolker
Ben Bolker

Reputation: 226911

When you extract a single row from a data frame you get a one-row data frame. Convert it to a numeric vector:

as.numeric(df[1,])

As @Roland suggests, unlist(df[1,]) will convert the one-row data frame to a numeric vector without dropping the names. Therefore unname(unlist(df[1,])) is another, slightly more explicit way to get to the same result.

As @Josh comments below, if you have a not-completely-numeric (alphabetic, factor, mixed ...) data frame, you need as.character(df[1,]) instead.

Upvotes: 221

sbha
sbha

Reputation: 10432

Here is a dplyr based option:

newV = df %>% slice(1) %>% unlist(use.names = FALSE)

# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()

Upvotes: 17

Rtist
Rtist

Reputation: 4205

Note that you have to be careful if your row contains a factor. Here is an example:

df_1 = data.frame(V1 = factor(11:15),
                  V2 = 21:25)
df_1[1,] %>% as.numeric() # you expect 11 21 but it returns 
[1] 1 21

Here is another example (by default data.frame() converts characters to factors)

df_2 = data.frame(V1 = letters[1:5],
                  V2 = 1:5)
df_2[3,] %>% as.numeric() # you expect to obtain c 3 but it returns
[1] 3 3
df_2[3,] %>% as.character() # this won't work neither
[1] "3" "3"

To prevent this behavior, you need to take care of the factor, before extracting it:

df_1$V1 = df_1$V1 %>% as.character() %>% as.numeric()
df_2$V1 = df_2$V1 %>% as.character()
df_1[1,] %>% as.numeric()
[1] 11  21
df_2[3,] %>% as.character()
[1] "c" "3"

Upvotes: 6

Roland
Roland

Reputation: 132989

I recommend unlist, which keeps the names.

unlist(df[1,])
  a   b   c 
1.0 2.0 2.6 

is.vector(unlist(df[1,]))
[1] TRUE

If you don't want a named vector:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6

Upvotes: 60

CHP
CHP

Reputation: 17189

If you don't want to change to numeric you can try this.

> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6

Upvotes: 9

Jonathan Christensen
Jonathan Christensen

Reputation: 3866

Columns of data frames are already vectors, you just have to pull them out. Note that you place the column you want after the comma, not before it:

> newV <- df[,1]
> newV
[1] 1 2 4 2

If you actually want a row, then do what Ben said and please use words correctly in the future.

Upvotes: -6

Related Questions