2

I have a dataframe df looking like this

    A     B     C     D
1   78    12    43    12
2   23    12    42    13
3   14    42    11    99
4   49    94    27    72

I need the first two columns converted into a list which looks exactly like this:

[[1]]
[1] 78 12

[[2]]
[1] 23 12

[[3]]
[1] 14 42

[[4]]
[1] 49 94

Basically what

list(c(78, 12), c(23, 12), c(14, 42), c(49, 94)

would do. I tried this

lapply(as.list(1:dim(df)[1]), function(x) df[x[1],])

as well as

lapply(as.list(1:nrow(df)), function(x) df)

But thats slightly different. Any suggestions?

four-eyes
  • 10,740
  • 29
  • 111
  • 220
  • 1
    How pedantic are you going to be about the absence of names in the resulting list? e.g. `split(df[,1:2],seq_len(nrow(df)))` – joran Jun 14 '16 at 16:36
  • @joran very. I need it exactly as I described.What the `list()` would do to various vectors... – four-eyes Jun 14 '16 at 16:38
  • Then do what I suggested and `unname` it twice, once with `lapply` and once at the top level. – joran Jun 14 '16 at 16:40
  • 1
    There's probably a cleaner way to do it: `out <- lapply(split(df[,1:2], seq(nrow(df))), function(x) as.numeric(x)); names(out) <- NULL` – Scott Warchal Jun 14 '16 at 16:40
  • @joran where would I do the two `unnames`? – four-eyes Jun 14 '16 at 16:41
  • 1
    I take it back, you can do `mapply(c,df$A,df$B,SIMPLIFY = FALSE)` if you really can't have the names. – joran Jun 14 '16 at 16:43
  • @Swarch thats it. I am having big troubles understand `plyr`... Thanks! – four-eyes Jun 14 '16 at 16:44
  • @Stophface No one has mentioned anything from the `plyr` package. But based on your comment you might want to read Joran's lovely answer about [R grouping functions](http://stackoverflow.com/a/7141669/903061). – Gregor Thomas Jun 14 '16 at 16:57
  • @joran is there a way to do that with `double` as well? My numbers in my rows are not `integers` but actually `double` – four-eyes Jun 14 '16 at 17:02
  • 1
    @Stophface Huh? What do doubles have to do with anything? – joran Jun 14 '16 at 17:04

3 Answers3

5

You can try the Map:

Map(c, df$A, df$B)
[[1]]
[1] 78 12

[[2]]
[1] 23 12

[[3]]
[1] 14 42

[[4]]
[1] 49 94
Psidom
  • 209,562
  • 33
  • 339
  • 356
0

In case this is of interest, it is possible to accomplish this with the foreach package:

library(foreach)
foreach(i=seq.int(nrow(df))) %do% (c(df[[i]][1], df[[i]][2]))

foreach returns a list by default. The code runs down the rows and pulls elements from the first and second columns.

An even cleaner to read version:

foreach(i=seq.int(nrow(df))) %do% (df[[i]][1:2])
lmo
  • 37,904
  • 9
  • 56
  • 69
0

Another option is with lapply

lapply(seq_len(nrow(df1)), function(i) unlist(df1[i, 1:2], use.names=FALSE))
#[[1]]
#[1] 78 12

#[[2]]
#[1] 23 12

#[[3]]
#[1] 14 42

#[[4]]
#[1] 49 94
akrun
  • 874,273
  • 37
  • 540
  • 662