有没有办法从codechunks获取第一次出现的值的rowID?

时间:2017-12-08 09:37:04

标签: r dplyr

谢谢大家的回答。他们一切都很好。 =) 有没有办法实现这一目标? 例如:(分布是随机的)

ID    size
1      x
2      x
3      x
4      x
5      x
0      2
0      x
0      x
0      x
4      x
5      x
0      4
0      x
0      x
0      x
4      x
5      x
0      3
0      x
0      x
0      x
4      x
5      x

这只是一个例子,但很难为我编码。 x是随机数字且不相关。我需要的值是size列中显示的整数,因此每次ID == 0时,我都需要第一个size值。任何的想法? TY

4 个答案:

答案 0 :(得分:2)

使用data.table::lag()创建一个落后ID后一行的新列。如果d是您的data.frame:

d <- d %>% dplyr::mutate(prevID = lag(ID))

   ID size prevID
1   1   44     NA
2   2   55      1
3   3   66      2
4   4   77      3
5   5   88      4
6   0    2      5
7   0   33      0
8   0   44      0
9   0   55      0
10  4   66      0
11  5   77      4
12  0    4      5
13  0   11      0
14  0   22      0
15  0   33      0
16  4   44      0
17  5   55      4
18  0    3      5
19  0   44      0
20  0   55      0
21  0   66      0
22  4   77      0
23  5   88      4

然后获取ID为0且不等于prevID的行 - 这些是第一行0

> which(d$ID == 0 & d$prevID != 0)
[1]  6 12 18

或者使用它来过滤原始data.frame:

> d[which(d$ID == 0 & d$prevID != 0), ]
# A tibble: 3 x 3
     ID  size prevID
  <int> <int>  <int>
1     0     2      5
2     0     4      5
3     0     3      5

答案 1 :(得分:0)

以下是使用Product::select('id', 'title','product_summary','description','min_price','rating_count') ->WhereHas('Package',function($q)use($string){ $q->orWhere(DB::raw('LOWER(name->>"$.en")'),'like',"%{$string}%") ->orWhere(DB::raw('LOWER(description->>"$.en")'),'like',"%{$string}%") ->orWhere(DB::raw('LOWER(product_summary->>"$.en")'),'like',"%{$string}%") ->orWhereHas('categories',function($subq)use($string){ $subq->orWhere(DB::raw('LOWER(name->>"$.en")'),'like',"%{$string}%"); }); }) ->WhereHas('country',function($q)use($string){ $q->orWhere('name','like',"%{$string}%"); })

中的rleid的想法
data.table

给出,

library(data.table)

setDT(dt)[, grp := rleid(ID == 0)][ID == 0, .(size = first(size)), by = grp]

grp size 1: 2 2 2: 4 4 3: 6 3 中,一个想法可以是,

tidyverse
ehich给出,

library(tidyverse)

df %>% 
 mutate(grp = cumsum(ID != 0)) %>% 
 filter(ID == 0) %>% 
 group_by(grp) %>% 
 summarise(size = first(size))

答案 2 :(得分:0)

希望这有帮助!

library(dplyr)
df %>%
  mutate(row_idx = row_number()) %>%
  filter(ID==0) %>%
  filter(row_idx-lag(row_idx)>1 | row_number()==1) %>%
  select(-row_idx)

输出是:

1  0    2
2  0    4
3  0    3


#sample data
> dput(df)
structure(list(ID = c(1L, 2L, 3L, 4L, 5L, 0L, 0L, 0L, 0L, 4L, 
5L, 0L, 0L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 4L, 5L), size = structure(c(4L, 
4L, 4L, 4L, 4L, 1L, 4L, 4L, 4L, 4L, 4L, 3L, 4L, 4L, 4L, 4L, 4L, 
2L, 4L, 4L, 4L, 4L, 4L), .Label = c("2", "3", "4", "x"), class = "factor")), .Names = c("ID", 
"size"), class = "data.frame", row.names = c(NA, -23L))

答案 3 :(得分:0)

或基础R解决方案:

df <- read.table(text = "
ID    size
1      1
2      5
3      6
4      7
5      8
0      2
0      5
0      7
0      9
4      0
5      3
0      4
0      5
0      1
0      4
4      7
5      9
0      3
0      5
0      6
0      9
4      9
5      4", header = T)

ids <- which(df$ID == 0)

temp  <- c(TRUE, (diff(ids) != 1))

df$size[ids[temp]]
#[1] 2 4 3