通过偏移选择行

时间:2015-06-11 23:56:30

标签: r subset

我有这个数据框,我们称之为my_df。 它看起来像这样:

my_df <- data.frame(rnorm(n = 30,sd=.5),rep(c("a","b","c"),each=10))
names(my_df) <- c("num","let")

head(my_df)
          num let
1  0.01202600   a
2  1.09025768   a
3 -0.08656178   a
4 -0.04847073   a
5 -0.63750258   a
6  0.58846135   a

我想要做的是选择my_df$let == "b"时的所有行以及my_df$let == "b"时第一行前面的五行,以及{{1}时最后一行后面的五行}。基本上my_df == "b"

我实际使用的数据是数十万行,而且我不知道哪些行是什么,而且每组数据都不符合行和我无法花时间单独浏览每组数据。我一直在使用子集来选择我想要的数据,但我不知道如何选择子集之外的其他行(前后1000行)。

这是我正在做的事情的子集:

my_df[6:25,]

我想选择上面代码选择的所有行,但在此之前我还想要100行,之后需要1000行。

如果您需要任何可能对您有帮助的其他信息,请询问。

3 个答案:

答案 0 :(得分:4)

以下是使用dplyr

的另一个想法
library(dplyr)
my_df %>% filter(lead(let == "b", 5) | lag(let == "b", 5))

或者根据@akrun建议使用devel版本的data.table

setDT(my_df)[shift(let == "b", 5) | shift(let == "b", type = "lead", 5)]

给出了:

#           num let
#1   0.36723709   a
#2   0.24743170   a
#3  -0.33339924   a
#4  -0.57024317   a
#5   0.03390278   a
#6  -0.43495096   b
#7  -0.85107347   b
#8   0.53048931   b
#9  -0.26739611   b
#10 -0.96029355   b
#11 -0.71737408   b
#12  0.34324685   b
#13  0.12319646   b
#14  0.75207703   b
#15  0.18134006   b
#16 -0.02230777   c
#17  0.42646106   c
#18 -0.11055478   c
#19  0.06013187   c
#20  0.50782158   c

答案 1 :(得分:1)

通常根据某些分类将数据框拆分为数据框列表很简单 - 您可以在案例中使用split(my_df, my_df$let)。但是,如果您想要在操作一组唯一分类之前或之后想要一些行,则会增加复杂性,在每种情况下选择所需的行:

before <- 5
after <- 5
ret <- setNames(lapply(unique(my_df$let), function(x) {
  positions <- which(my_df$let == x)
  start.pos <- max(1, min(positions)-before)
  end.pos <- min(nrow(my_df), max(positions)+after)
  my_df[start.pos:end.pos,]
}), unique(my_df$let))

您可以从返回的列表中获取所需类别的观察结果:

ret$b  # Also works: ret[["b"]]
#             num let
# 6  -0.197901427   a
# 7   0.194607192   a
# 8  -0.107318203   a
# 9  -0.365313233   a
# 10 -0.188926562   a
# 11  0.636272295   b
# 12 -0.058791973   b
# 13 -0.231029510   b
# 14  0.519441716   b
# 15  0.239510912   b
# 16  0.107025658   b
# 17 -0.446644081   b
# 18  0.145052077   b
# 19 -0.426090749   b
# 20 -0.356062993   b
# 21 -0.155012203   c
# 22 -0.007968255   c
# 23 -0.504253089   c
# 24  0.081624303   c
# 25 -0.657008233   c

答案 2 :(得分:0)

我最近回答了一个几乎相同的问题:Select n rows after specific number。使单段解决方案适应您的数据:

set.seed(1); my_df <- data.frame(rnorm(n = 30,sd=.5),rep(c("a","b","c"),each=10));
names(my_df) <- c("num","let");
brange <- range(which(my_df$let=='b'));
my_df$offb <- c((1-brange[1]):-1,rep(0,diff(brange)+1),1:(nrow(my_df)-brange[2]));
my_df;
##             num let offb
## 1  -0.313226905   a  -10
## 2   0.091821662   a   -9
## 3  -0.417814306   a   -8
## 4   0.797640401   a   -7
## 5   0.164753886   a   -6
## 6  -0.410234192   a   -5
## 7   0.243714526   a   -4
## 8   0.369162353   a   -3
## 9   0.287890676   a   -2
## 10 -0.152694194   a   -1
## 11  0.755890584   b    0
## 12  0.194921618   b    0
## 13 -0.310620290   b    0
## 14 -1.107349944   b    0
## 15  0.562465459   b    0
## 16 -0.022466805   b    0
## 17 -0.008095132   b    0
## 18  0.471918105   b    0
## 19  0.410610598   b    0
## 20  0.296950661   b    0
## 21  0.459488686   c    1
## 22  0.391068150   c    2
## 23  0.037282492   c    3
## 24 -0.994675848   c    4
## 25  0.309912874   c    5
## 26 -0.028064370   c    6
## 27 -0.077897753   c    7
## 28 -0.735376192   c    8
## 29 -0.239075028   c    9
## 30  0.208970780   c   10
subset(my_df,offb>=-5&offb<=5);
##             num let offb
## 6  -0.410234192   a   -5
## 7   0.243714526   a   -4
## 8   0.369162353   a   -3
## 9   0.287890676   a   -2
## 10 -0.152694194   a   -1
## 11  0.755890584   b    0
## 12  0.194921618   b    0
## 13 -0.310620290   b    0
## 14 -1.107349944   b    0
## 15  0.562465459   b    0
## 16 -0.022466805   b    0
## 17 -0.008095132   b    0
## 18  0.471918105   b    0
## 19  0.410610598   b    0
## 20  0.296950661   b    0
## 21  0.459488686   c    1
## 22  0.391068150   c    2
## 23  0.037282492   c    3
## 24 -0.994675848   c    4
## 25  0.309912874   c    5