使用 dplyr 总结条件
Using dplyr summarise with conditions
我目前正在尝试应用汇总功能,以便从大型数据集中分离出相关观察结果。这里给出了一个简单的可重现示例:
df <- data.frame(c(1,1,1,2,2,2,3,3,3), as.logical(c(TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE)),
as.numeric(c(0,5,0,0,0,0,7,0,7)))
colnames(df) <- c("ID", "Status", "Price")
ID Status Price
1 1 TRUE 0
2 1 FALSE 5
3 1 TRUE 0
4 2 TRUE 0
5 2 TRUE 0
6 2 TRUE 0
7 3 FALSE 7
8 3 TRUE 0
9 3 FALSE 7
我想通过观察对 table 进行排序,只有当所有三个观察结果都为 TRUE(计算出来)时才获得状态 TRUE,然后想要获得与状态对应的价格(即 5 用于观察1 为假,0 表示观察 2 为真,7 表示观察 3 为假)。
从 Summarize with conditions in dplyr 我发现我可以 - 就像往常一样 - 在方括号中指定条件。到目前为止,我的代码如下所示:
library(dplyr)
result <- df %>%
group_by(ID) %>%
summarize(Status = all(Status), Test = ifelse(all(Status) == TRUE,
first(Price[Status == TRUE]), first(Price[Status == FALSE])))
# This is what I get:
# A tibble: 3 x 3
ID Status Test
<dbl> <lgl> <dbl>
1 1. FALSE 0.
2 2. TRUE 0.
3 3. FALSE 7.
但是如您所见,对于 ID = 1,它给出的价格不正确。我一直在尝试这个,所以我很感激任何关于我哪里出错的提示。
可以做到:
df %>%
group_by(ID) %>%
mutate(status = Status) %>%
summarise(
Status = all(Status),
Test = ifelse(Status == TRUE,
first(Price),
first(Price[status == FALSE]))
)
输出:
# A tibble: 3 x 3
ID Status Test
<dbl> <lgl> <dbl>
1 1 FALSE 5
2 2 TRUE 0
3 3 FALSE 7
问题是您想要将 Status
用于 Test
列,而您已经对其进行了修改,使其不再包含原始值。
之前复制一份(我保存在status
),执行ifelse
就可以了运行
我们可以将 all(Status)
保留为 summarise
中的第二个参数(或更改列名),而且可以使用 if/else
来完成,因为逻辑似乎 return 单个 TRUE/FALSE 基于 'Status' 的 all
是否为 TRUE
df %>%
group_by(ID) %>%
summarise( Test = if(all(Status)) first(Price[Status]) else
first(Price[!Status]), Status = all(Status))
# A tibble: 3 x 3
# ID Test Status
# <dbl> <dbl> <lgl>
#1 1 5 FALSE
#2 2 0 TRUE
#3 3 7 FALSE
注意:最好不要使用长度不等的参数ifelse
我目前正在尝试应用汇总功能,以便从大型数据集中分离出相关观察结果。这里给出了一个简单的可重现示例:
df <- data.frame(c(1,1,1,2,2,2,3,3,3), as.logical(c(TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE)),
as.numeric(c(0,5,0,0,0,0,7,0,7)))
colnames(df) <- c("ID", "Status", "Price")
ID Status Price
1 1 TRUE 0
2 1 FALSE 5
3 1 TRUE 0
4 2 TRUE 0
5 2 TRUE 0
6 2 TRUE 0
7 3 FALSE 7
8 3 TRUE 0
9 3 FALSE 7
我想通过观察对 table 进行排序,只有当所有三个观察结果都为 TRUE(计算出来)时才获得状态 TRUE,然后想要获得与状态对应的价格(即 5 用于观察1 为假,0 表示观察 2 为真,7 表示观察 3 为假)。
从 Summarize with conditions in dplyr 我发现我可以 - 就像往常一样 - 在方括号中指定条件。到目前为止,我的代码如下所示:
library(dplyr)
result <- df %>%
group_by(ID) %>%
summarize(Status = all(Status), Test = ifelse(all(Status) == TRUE,
first(Price[Status == TRUE]), first(Price[Status == FALSE])))
# This is what I get:
# A tibble: 3 x 3
ID Status Test
<dbl> <lgl> <dbl>
1 1. FALSE 0.
2 2. TRUE 0.
3 3. FALSE 7.
但是如您所见,对于 ID = 1,它给出的价格不正确。我一直在尝试这个,所以我很感激任何关于我哪里出错的提示。
可以做到:
df %>%
group_by(ID) %>%
mutate(status = Status) %>%
summarise(
Status = all(Status),
Test = ifelse(Status == TRUE,
first(Price),
first(Price[status == FALSE]))
)
输出:
# A tibble: 3 x 3
ID Status Test
<dbl> <lgl> <dbl>
1 1 FALSE 5
2 2 TRUE 0
3 3 FALSE 7
问题是您想要将 Status
用于 Test
列,而您已经对其进行了修改,使其不再包含原始值。
之前复制一份(我保存在status
),执行ifelse
就可以了运行
我们可以将 all(Status)
保留为 summarise
中的第二个参数(或更改列名),而且可以使用 if/else
来完成,因为逻辑似乎 return 单个 TRUE/FALSE 基于 'Status' 的 all
是否为 TRUE
df %>%
group_by(ID) %>%
summarise( Test = if(all(Status)) first(Price[Status]) else
first(Price[!Status]), Status = all(Status))
# A tibble: 3 x 3
# ID Test Status
# <dbl> <dbl> <lgl>
#1 1 5 FALSE
#2 2 0 TRUE
#3 3 7 FALSE
注意:最好不要使用长度不等的参数ifelse