2

I have a vector 'a' that is a numerical vector of row indices. I'd like to get these rows as well as the next 20 rows next to them out of a dataframe called 'data'. Is there a way to do this?

I've already tried:
data2 <- data[a:a+20,] but without success.

If a <- c(1, 21, 42) I'd like to extract rows 1:20, 21:41, and 42:62 from 'data' and store them in another object.

bactro
  • 79
  • 6
  • `data2 <- data[-a,]` ? Your question isn't very clear. What do you expect the final dataframe to look like? Are you trying to get a single dataframe or a list of three dataframes? An actual example (perhaps using a built-in dataset like `trees`) would help. – John Coleman Jul 21 '19 at 00:37
  • Sorry I wasn't clear. I want actually a single dataframe rowbind of 1:20, 21:41, 31:41 (but with values specified by values in the vector a). The end result is basically a subset of the original dataframe. – bactro Jul 21 '19 at 00:45
  • How do you get from `c(1,21,31)` to `1:20, 21:41, 31:41`? For one thing, where did `41` come from? Furthermore, wouldn't `1:20, 21:41, 31:41` duplicate the rows in `31:41`, making the resulting dataframe no longer a subset? – John Coleman Jul 21 '19 at 00:47
  • I edited my question to fix that, my mistake. What I mean was, I have a vector of single numeric values (these values represent rows in a dataframe, ex. 1 represents row 1, 21 represents row 21 etc.) I want to take this vector, add 20 to the values, and extract ALL those rows from the dataset. Hope this was clearer. Thanks! – bactro Jul 21 '19 at 00:58
  • Why not ```data[1:62, ]```? Or if you have a vector, ```data[min(a):max(a), ]```. – Cole Jul 21 '19 at 01:08

3 Answers3

6

Here is another way from base without fancy functions and for loops:

data2 <- data[rep(a, each = 21) + 0:20,]
Grada Gukovic
  • 1,228
  • 7
  • 13
1

If I understand you, the following should work:

do.call("rbind",lapply(a,function(i) data[i:(i+20),]))

See this question about how to convert a list of dataframes to a singe dataframe (which is the least intuitive part of my answer). The answers to that question give ways more intuitive than do.call(), but require going beyond base R.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
  • @bactro This was the first thing that I thought of, but I think that the solution of Grada Gukovic is superior. Consider accepting their answer rather than mine. – John Coleman Jul 21 '19 at 20:06
1

Here's a way using Map from base R -

data[unlist(Map(`:`, a, a+20)), ]

Or with sapply (similar to John's answer) -

data[c(sapply(a, function(x) x:(x+20))), ]
Shree
  • 10,835
  • 1
  • 14
  • 36