164

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 
6
  • I suggest you format the data you've shown properly. Looks like you are missing some line breaks. Commented Jan 23, 2013 at 16:41
  • I want a row. Row '1' and not column 'a'. Commented Jan 23, 2013 at 16:53
  • Is there a way to apply this to all rows of a data frame and thereby merging all vectors to a single vector? Commented Aug 9, 2019 at 9:32
  • 2
    @stephanmg: What about something like: c(t(as.matrix(df)))? Commented Sep 25, 2019 at 14:01
  • Andri: That's working, though I could solve it differently too. Commented Sep 26, 2019 at 13:20

7 Answers 7

222

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.

Sign up to request clarification or add additional context in comments.

14 Comments

it might be +1 (or 0 down-votes) to the OP for giving code that illustrated clearly what they wanted even though the text and title of the question were garbled ...
@ChinmayPatil, what are their other options? Their code example certainly makes it look like that's what they want.
It should be noted that a data frame is already a vector and hence as.vector sees it is a vector of mode "list" and does nothing. To facilitate understanding of the underlying mechanisms try as.vector(df[1,], mode="numeric") which is more illustrative. This is what as.numeric does.
no problem. I'm only stating that for this problem they give exactly the same answer.
Might have been changed in the meantime, but today unlist allows dropping names: identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,])) (and btw df still is not a sensible name for a data.frame... ;-))
|
60

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 

Comments

17

Here is a dplyr based option:

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

Comments

9

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 

6 Comments

this doesn't make much sense to me: str(as.vector(t(df)[,1])) is num [1:3] 1 2 2.6, i.e. your code does convert the results to a numeric vector ...
specifically, when you use t(df) R coerces the data frame to a matrix, in this case a numeric matrix because all the elements are numeric. Then [,1] extracts the first column (a numeric vector, because the redundant dimension is automatically dropped). as.vector() just drops the names (which you could also do with unname()).
It seems to work for characters as well. But you are right about coersion. FWIW, my solution will work on character data frames as well.. with caveat of all the data being converted to character
I would say that the unname(unlist(x)) solution is a little better (more efficient and more transparent).
as.vector(t(df)[,1]) I love it ! Exactly what I need it !
|
6

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" 

1 Comment

Indeed, factorized columns are problematic in this case. Is there a way to automatize this rather than unfactorizing the columnns one by one?
0

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.

Comments

-6

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.

2 Comments

but I think the OP wants the first row ?
@BenBolker Maybe so... I just assumed that he wanted what his title and question said he wanted.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.