聚合条件语句
Aggregate conditional statements
我正在尝试找到一种优雅的解决方案,无需逐行迭代进行复杂的子集 and/or。我将通过示例进行解释:
# Load data
df1 <- mtcars
# Can aggregate with simple math functions i.e. mean or sum
hp_by_cyl <- aggregate(hp ~ cyl, data=df1, mean)
> hp_by_cyl
cyl hp
1 4 82.63636
2 6 122.28571
3 8 209.21429
好的。但是,在我真正复杂得多的数据中,我希望聚合一个逻辑值——即如果 x 对于属于类别 A 的任何行为真,则 y = 1。因此,为了扩展我的示例,我可以创建一个包含逻辑变量的列:
df1$logic <- ifelse(df1$gear==4 & df1$hp < 150, 1, 0)
# How do I aggregate the logical values levels of cyl to answer yes/no
# if any car with x cylinders has 4 gears and < 150 hp ?
# So I want an finished table like this:
cyl logic
4 1
6 1
8 0
所以我的问题是如何使用聚合(或备用)命令生成这样的 table? 即结合逻辑状态,而不是数字状态值 ?
我还需要在现实中处理编码的缺失值,因此为了模拟这种复杂性,我将制作逻辑 99 之一:
df1[5, ]$logic <- 99
如果对于 cyl
的给定级别,一个值为 1,则可以忽略 99 - 但是,如果所有其他值为 0,则合计应为 99。
很抱歉,如果有一个简单的答案我没有在我的真实数据中看到它看起来令人生畏。我可以破解出一个讨厌的解决方案,但我知道它会非常慢,而且我有一个 14000 X 140 大小的数据集。提前谢谢大家。
我想这就是你想要的:
aggregate(hp~cyl,data=mtcars,function(x) ifelse(mean(x)<150,1,0))
编辑:
dplyr
是你的朋友:
mtcars %>% group_by_(~cyl) %>% summarise_(logic=~ifelse(mean(hp)<150 & sum(wt)>3,1,0))
这是一个更复杂的逻辑陈述,希望对您有所帮助。如果您想一次处理 2 个以上的变量,aggregate
不是最佳方法。
首先,不要理会 0/1/99,留下它 TRUE/FALSE/NA。
df1$logic <- df1$gear==4 & df1$hp < 150
然后与 any
或 tapply
聚合。
aggregate(logic ~ cyl, data=df1, any)
## cyl logic
## 1 4 TRUE
## 2 6 TRUE
## 3 8 FALSE
with(df1, tapply(logic, cyl, any))
## 4 6 8
## TRUE TRUE FALSE
plyr 包,特别是 ddply
函数,是许多人认为更直观的另一个选项。
library(plyr)
ddply(df1, ~cyl, summarize, isany = any(gear==4 & hp < 150))
## cyl isany
## 1 4 TRUE
## 2 6 TRUE
## 3 8 FALSE
我正在尝试找到一种优雅的解决方案,无需逐行迭代进行复杂的子集 and/or。我将通过示例进行解释:
# Load data
df1 <- mtcars
# Can aggregate with simple math functions i.e. mean or sum
hp_by_cyl <- aggregate(hp ~ cyl, data=df1, mean)
> hp_by_cyl
cyl hp
1 4 82.63636
2 6 122.28571
3 8 209.21429
好的。但是,在我真正复杂得多的数据中,我希望聚合一个逻辑值——即如果 x 对于属于类别 A 的任何行为真,则 y = 1。因此,为了扩展我的示例,我可以创建一个包含逻辑变量的列:
df1$logic <- ifelse(df1$gear==4 & df1$hp < 150, 1, 0)
# How do I aggregate the logical values levels of cyl to answer yes/no
# if any car with x cylinders has 4 gears and < 150 hp ?
# So I want an finished table like this:
cyl logic
4 1
6 1
8 0
所以我的问题是如何使用聚合(或备用)命令生成这样的 table? 即结合逻辑状态,而不是数字状态值 ?
我还需要在现实中处理编码的缺失值,因此为了模拟这种复杂性,我将制作逻辑 99 之一:
df1[5, ]$logic <- 99
如果对于 cyl
的给定级别,一个值为 1,则可以忽略 99 - 但是,如果所有其他值为 0,则合计应为 99。
很抱歉,如果有一个简单的答案我没有在我的真实数据中看到它看起来令人生畏。我可以破解出一个讨厌的解决方案,但我知道它会非常慢,而且我有一个 14000 X 140 大小的数据集。提前谢谢大家。
我想这就是你想要的:
aggregate(hp~cyl,data=mtcars,function(x) ifelse(mean(x)<150,1,0))
编辑:
dplyr
是你的朋友:
mtcars %>% group_by_(~cyl) %>% summarise_(logic=~ifelse(mean(hp)<150 & sum(wt)>3,1,0))
这是一个更复杂的逻辑陈述,希望对您有所帮助。如果您想一次处理 2 个以上的变量,aggregate
不是最佳方法。
首先,不要理会 0/1/99,留下它 TRUE/FALSE/NA。
df1$logic <- df1$gear==4 & df1$hp < 150
然后与 any
或 tapply
聚合。
aggregate(logic ~ cyl, data=df1, any)
## cyl logic
## 1 4 TRUE
## 2 6 TRUE
## 3 8 FALSE
with(df1, tapply(logic, cyl, any))
## 4 6 8
## TRUE TRUE FALSE
plyr 包,特别是 ddply
函数,是许多人认为更直观的另一个选项。
library(plyr)
ddply(df1, ~cyl, summarize, isany = any(gear==4 & hp < 150))
## cyl isany
## 1 4 TRUE
## 2 6 TRUE
## 3 8 FALSE