我使用键id
和time
构建以下面板数据:
pdata <- tibble(
id = rep(1:10, each = 5),
time = rep(2016:2020, times = 10),
value = c(c(1,1,1,0,0), c(1,1,0,0,0), c(0,0,1,0,0), c(0,0,0,0,0), c(1,0,0,0,1), c(0,1,1,1,0), c(0,1,1,1,1), c(1,1,1,1,1), c(1,0,1,1,1), c(1,1,0,1,1))
)
pdata
# A tibble: 50 × 3
id time value
<int> <int> <dbl>
1 1 2016 1
2 1 2017 1
3 1 2018 1
4 1 2019 0
5 1 2020 0
6 2 2016 1
7 2 2017 1
8 2 2018 0
9 2 2019 0
10 2 2020 0
# … with 40 more rows
让我们假设2018年发生了一次冲击。我希望通过id
对上一行和下一行进行切片,这些行的值与shock行的值相同。
我举几个例子来说明。对于id==5
,数据集如下所示:
pdata %>% filter(id == 5)
# A tibble: 5 × 3
id time value
<int> <int> <dbl>
1 5 2016 1
2 5 2017 0
3 5 2018 0
4 5 2019 0
5 5 2020 1
2018年id==5
的值为0,我希望保留上一行和下一行,包括当前行,因为所有这些观察值都具有相同的值,等于0。
# A tibble: 3 × 3
id time value
<int> <int> <dbl>
1 5 2017 0
2 5 2018 0
3 5 2019 0
对于
id==8
,我希望得到:
# A tibble: 5 × 3
id time value
<int> <int> <dbl>
1 8 2016 1
2 8 2017 1
3 8 2018 1
4 8 2019 1
5 8 2020 1
对于
id==1
,我希望获得空数据集,因为2017年的观察结果和2019年的观察结果对不具有相同的值。
最终数据集应为:
# A tibble: 19 × 3
id time value
<int> <int> <dbl>
1 4 2016 0
2 4 2017 0
3 4 2018 0
4 4 2019 0
5 4 2020 0
6 5 2017 0
7 5 2018 0
8 5 2019 0
9 6 2017 1
10 6 2018 1
11 6 2019 1
12 7 2017 1
13 7 2018 1
14 7 2019 1
15 8 2016 1
16 8 2017 1
17 8 2018 1
18 8 2019 1
19 8 2020 1
据我所知,这里有一个dplyr
建议:
library(dplyr)
MyF <- function(id2, shock, nb_row) {
values <- pdata %>%
filter(id == id2) %>%
pull(value)
if (length(unique(values)) == 1) {
pdata %>%
filter(id == id2)
} else {
pdata %>%
filter(id == id2) %>%
filter(time >= shock - nb_row & time <= shock + nb_row) %>%
filter(length(unique(value)) == 1)
}
}
map_df(pdata %>%
select(id) %>%
distinct() %>%
pull(),
MyF,
shock = 2018, nb_row = 1)
## Or map_df(1:8,MyF,shock = 2018, nb_row = 1)
输出:
# A tibble: 19 x 3
id time value
<int> <int> <dbl>
1 4 2016 0
2 4 2017 0
3 4 2018 0
4 4 2019 0
5 4 2020 0
6 5 2017 0
7 5 2018 0
8 5 2019 0
9 6 2017 1
10 6 2018 1
11 6 2019 1
12 7 2017 1
13 7 2018 1
14 7 2019 1
15 8 2016 1
16 8 2017 1
17 8 2018 1
18 8 2019 1
19 8 2020 1
在每个“id”(by=id
)中,使用rleid
基于相等值的运行创建分组变量“r”。在每个“id”和运行(by=(id,r)
)中,检查是否至少存在焦点年(例如2018年)的上一年和下一年(if(总和(时间百分比,年)==3)
)。如果是这样,请在焦点年前后选择相同数量的行(min(c(shock-.I[1],.I[.N]-shock)
)。请注意,此处选择的年数可能因“id”而异。
library(data.table)
setDT(pdata)
yr = 2018
yr_rng = (yr - 1):(yr + 1)
pdata[ , r := rleid(value), by = id]
pdata[pdata[ , if(sum(time %in% yr_rng) == 3) {
shock = .I[time == 2018]
rng = min(c(shock - .I[1], .I[.N] - shock))
(shock - rng):(shock + rng)
}, by = .(id, r)]$V1]
id time value r
1: 4 2016 0 1
2: 4 2017 0 1
3: 4 2018 0 1
4: 4 2019 0 1
5: 4 2020 0 1
6: 5 2017 0 2
7: 5 2018 0 2
8: 5 2019 0 2
9: 6 2017 1 2
10: 6 2018 1 2
11: 6 2019 1 2
12: 7 2017 1 2
13: 7 2018 1 2
14: 7 2019 1 2
15: 8 2016 1 1
16: 8 2017 1 1
17: 8 2018 1 1
18: 8 2019 1 1
19: 8 2020 1 1
在每个“id”和运行(by=(id,r)
)中,检查重点年份(例如2018年)的上一年和下一年是否都存在(if(总和(时间百分比,年)==3)
)。如果是,请选择整个组(.SD
)。
pdata[ , r := rleid(value), by = id]
pdata[ , if(sum(time %in% yr_rng) == 3) .SD, by = .(id, r)]
id r time value
1: 4 1 2016 0
2: 4 1 2017 0
3: 4 1 2018 0
4: 4 1 2019 0
5: 4 1 2020 0
6: 5 2 2017 0
7: 5 2 2018 0
8: 5 2 2019 0
9: 6 2 2017 1
10: 6 2 2018 1
11: 6 2 2019 1
12: 7 2 2017 1
13: 7 2 2018 1
14: 7 2 2019 1
15: 7 2 2020 1
16: 8 1 2016 1
17: 8 1 2017 1
18: 8 1 2018 1
19: 8 1 2019 1
20: 8 1 2020 1
data.table解决方案:
# load the package & convert data to a data.table
library(data.table)
setDT(pdata)
# define shock-year and number of previous/next rows
shock <- 2018
n <- 2
# filter
pdata[, .SD[value == value[time == shock] &
between(time, shock - n, shock + n) &
value == rev(value)][.N > 1 & all(diff(time) == 1)]
, by = id]
其中:
id time value
1: 4 2016 0
2: 4 2017 0
3: 4 2018 0
4: 4 2019 0
5: 4 2020 0
6: 5 2017 0
7: 5 2018 0
8: 5 2019 0
9: 6 2017 1
10: 6 2018 1
11: 6 2019 1
12: 7 2017 1
13: 7 2018 1
14: 7 2019 1
15: 8 2016 1
16: 8 2017 1
17: 8 2018 1
18: 8 2019 1
19: 8 2020 1
使用数据:
pdata <- data.frame(
id = rep(1:10, each = 5),
time = rep(2016:2020, times = 10),
value = c(c(1,1,1,0,0), c(1,1,0,0,0), c(0,0,1,0,0), c(0,0,0,0,0), c(1,0,0,0,1), c(0,1,1,1,0), c(0,1,1,1,1), c(1,1,1,1,1), c(1,0,1,1,1), c(1,1,0,1,1))
)
问题内容: 假设我有这个(MySQL)数据库,按增加的时间戳排序: 如何从该系统的上一行中选择StatusA更改的行?StatusB无关紧要(我在此问题中展示它只是为了说明每个系统可能有许多连续的行,其中StatusA不变)。在上面的示例中,查询应返回2011-01-03行(对于SystemA,StatusA在2011-01-01和2011-01-03之间更改),2011-01-06、2011-0
问题内容: 我有一张桌子,像这样: 我想选择具有相同基因座和染色体的所有行。例如,第3行和第4行。一次可能有2个以上,并且它们可能不是按顺序排列的。 我尝试了这个: 但是,即使重复,它总是返回第3行,从不返回第4行。我想我缺少明显而简单的东西,但我茫然。 有人可以帮忙吗? 问题答案: 您需要了解,当您在查询中包含内容时,您是在告诉SQL合并行。您将为每个唯一值获得一行。在随后过滤这些组。通常,您可
我有一个学生表和一个成绩表。 < li >学生具有学生id(主键)、姓名、出生日期、地址、电子邮件和级别列。 < li>Grades包含列student_id(主/外键)、course_id(主/外键)和grade。 “成绩”如下所示: 这不是整个表格,但你明白了要点。我正在尝试编写一个查询,选择学生的姓名和该学生的最高分。由于我是SQL的新手,所以这对我来说有点令人困惑。到目前为止,我的尝试是这
本文向大家介绍根据DataFrame某一列的值来选择具体的某一行方法,包括了根据DataFrame某一列的值来选择具体的某一行方法的使用技巧和注意事项,需要的朋友参考一下 原始数据的DF: 此时,我要选择列名isInfected为“手足口病”的样本行: 总结:选择DataFrame里面某一列等于某个值的所有行,用一条命令即可解决即: 以上这篇根据DataFrame某一列的值来选择具体的某一行方法就
问题内容: 该主题的解决方案使我不知所措。 我有一个看起来像的表格(除与我的问题无关的其他字段之外): 名称,卡号,会员类型 现在,我想要一个显示卡号和成员类型相同的行的视图。这两个字段都是整数。名称为VARCHAR。名称不是唯一的,并且相同的名称也应显示重复的卡号,会员类型。 即,如果下表是表格: 我想要: 只需按卡号排序即可使其对人类有用。 最有效的方法是什么? 问题答案: 由于您提到的名称可
exTab 如何使用SQL(与mySQL一起)只返回col1中具有多个相同值、col2中具有多个相同值、但COL3中具有唯一值的行? 例如,在上面的表(exTab)中,val1在col1中出现了4次,对于这4次,val4在col2中出现了3次,但是对于这3次,val7在col3中只出现了一次,所以我想返回这一行(第1行)。考虑到这些条件,第1行将是我希望从此表返回的唯一一行。 我试过和group