r - 以 R 中另一列中的切换布尔变量为条件选择数据框中的行
问题描述
假设我在 R 中有以下数据框:
set.seed(23)
# Create sample data
time = 1:15
x = rnorm(n = 15)
y = rnorm(n = 15)
boolean = sample(c(TRUE,FALSE), 15, TRUE)
df <- data.frame(time, x, y, boolean)
# Output
> df
time x y boolean
1 1 0.19321233 0.308136896 TRUE
2 2 -0.43468211 -0.520178315 TRUE
3 3 0.91326710 -0.442313801 FALSE # select
4 4 1.79338809 -0.599312812 TRUE # select
5 5 0.99660511 1.294577829 TRUE
6 6 1.10749049 0.835391247 TRUE
7 7 -0.27808628 -0.566015100 TRUE
8 8 1.01920549 0.788419350 FALSE # select
9 9 0.04543718 -1.165929326 TRUE # select
10 10 1.57577959 -0.530820006 FALSE # select
11 11 0.21828845 -0.001058737 FALSE
12 12 -1.04653534 -0.512562365 FALSE
13 13 -0.28868865 1.242867513 FALSE
14 14 0.48155029 -0.660582851 FALSE
15 15 -1.21637643 0.166624215 TRUE # select
问题
我想选择所有行,其中第 4 列中的布尔值从FALSE
到切换,TRUE
反之亦然(如上面的数据框所示)。
问题
我如何在 R 中做到这一点?
试图
我在 中找到select()
和select_if()
函数tidyverse package
,但是,我无法根据列中的前一个值选择值。
解决方案
我们可以用来创建一个计数器,它随着值rle
的每次变化而递增。boolean
我们duplicated
只为每个计数器使用并选择第一行。这也将选择第一行,但由于它不是boolean
值的实际变化,我们删除该行(通过使用[-1]
)。
df[!duplicated(with(rle(df$boolean), rep(seq_along(values), lengths))), ][-1, ]
# time x y boolean
#2 2 -0.43468211 -0.566015100 TRUE
#3 3 0.91326710 0.788419350 FALSE
#6 6 1.10749049 -0.001058737 TRUE
#8 8 1.01920549 1.242867513 FALSE
#9 9 0.04543718 -0.660582851 TRUE
#13 13 -0.28868865 -1.146665860 FALSE
#15 15 -1.21637643 -0.202111683 TRUE
可以应用相同的逻辑data.table::rleid
,这将使其更短
df[!duplicated(data.table::rleid(df$boolean)), ][-1, ]
在中,我们可以使用和dplyr
创建组,并选择每个组的第一行。lag
cumsum
library(dplyr)
df %>%
group_by(group = cumsum(boolean != lag(boolean, default = first(boolean)))) %>%
slice(1L) %>%
ungroup %>%
slice(-1L) %>%
select(-group)
数据
df <- structure(list(time = 1:15, x = c(0.19321233, -0.43468211, 0.9132671,
1.79338809, 0.99660511, 1.10749049, -0.27808628, 1.01920549,
0.04543718, 1.57577959, 0.21828845, -1.04653534, -0.28868865,
0.48155029, -1.21637643), y = c(0.835391247, -0.5660151, 0.78841935,
-1.165929326, -0.530820006, -0.001058737, -0.512562365, 1.242867513,
-0.660582851, 0.166624215, -0.55320524, 0.098181415, -1.14666586,
-1.249927257, -0.202111683), boolean = c(FALSE, TRUE, FALSE,
FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE,
FALSE, TRUE)), class = "data.frame", row.names = c("1", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14","15"))
推荐阅读
- java - Java Streams GroupingBy 和按计数过滤(类似于 SQL 的 HAVING)
- javascript - 当窗口重新加载预向下滚动时,scrollTop 位置不一致
- laravel - 使用 vue js 引导表单助手
- elasticsearch - 将文档与存储在弹性搜索中的通配符/正则表达式匹配
- c# - 如何将所选参数从下拉列表发送到文件后面的 C# 代码以代替 User.Identity.Name?
- python - 转换为时间序列表
- es6-modules - 转换 CommonJS 要求语句以通过 ES6 导入加载?
- android - Android,从 Firestore 恢复时间戳
- reactjs - KendoReact 和 react-hook-form
- sql-server - nvarchar() 是否会对 SQL 执行时间产生负面影响?