根据另一个分组变量以不同方式切割变量
Cut a variable differently based on another grouping variable
示例:我有一个按性别划分的身高数据集。
我想将身高分成低和高,其中切点定义为平均值 - 每个性别的 2sd。
示例数据集:
set.seed(8)
df = data.frame(sex = c(rep("M",100), rep("F",100)),
ht = c(rnorm(100, mean=1.7, sd=.17), rnorm(100, mean=1.6, sd=.16)))
我想在一行矢量化代码中做一些事情,因为我相当确定这是可能的,但是,我不知道如何编写它。我想象可能有一种方法可以使用 cut()
、apply()
、and/or dplyr
来实现这一点。
刚刚使用 base r 发现了以下解决方案:
df$ht_grp <- ave(x = df$ht, df$sex,
FUN = function(x)
cut(x, breaks = c(0, (mean(x, na.rm=T) - 2*sd(x, na.rm=T)), Inf)))
这是有效的,因为我知道 0 和 Inf 是合理的界限,但我也可以使用 min(x)
和 max(x)
作为我的上限和下限。这导致因子变量被分为低、高和 NA。
我之前的解决方案:
我想出了以下两步过程,还不错:
df = merge(df,
setNames( aggregate(ht ~ sex, df, FUN = function(x) mean(x)-2*sd(x)),
c("sex", "ht_cutoff")),
by = "sex")
df$ht_is_low = ifelse(df$ht <= df$ht_cutoff, 1, 0)
如何使用来自基数 R 的 cut
:
sapply(c("F", "M"), function(s){
dfF <- df[df$sex==s,] # filter out per gender
cut(dfF$ht, breaks = c(0, mean(dfF$ht)-2*sd(dfF$ht), Inf), labels = c("low", "high"))
})
# dfF$ht heights per gender
# mean(dfF$ht)-2*sd(dfF$ht) cut point
在下面的代码中,我创建了 2 个新变量。两者都是通过对 sex
变量进行分组并过滤 ht
的不同范围而创建的。
library(dplyr)
df_low <- df %>% group_by(sex) %>% filter(ht<(mean(ht)-2*sd(ht)))
df_high<- df %>% group_by(sex) %>% filter(ht>(mean(ht)+2*sd(ht)))
示例:我有一个按性别划分的身高数据集。 我想将身高分成低和高,其中切点定义为平均值 - 每个性别的 2sd。
示例数据集:
set.seed(8)
df = data.frame(sex = c(rep("M",100), rep("F",100)),
ht = c(rnorm(100, mean=1.7, sd=.17), rnorm(100, mean=1.6, sd=.16)))
我想在一行矢量化代码中做一些事情,因为我相当确定这是可能的,但是,我不知道如何编写它。我想象可能有一种方法可以使用 cut()
、apply()
、and/or dplyr
来实现这一点。
刚刚使用 base r 发现了以下解决方案:
df$ht_grp <- ave(x = df$ht, df$sex,
FUN = function(x)
cut(x, breaks = c(0, (mean(x, na.rm=T) - 2*sd(x, na.rm=T)), Inf)))
这是有效的,因为我知道 0 和 Inf 是合理的界限,但我也可以使用 min(x)
和 max(x)
作为我的上限和下限。这导致因子变量被分为低、高和 NA。
我之前的解决方案: 我想出了以下两步过程,还不错:
df = merge(df,
setNames( aggregate(ht ~ sex, df, FUN = function(x) mean(x)-2*sd(x)),
c("sex", "ht_cutoff")),
by = "sex")
df$ht_is_low = ifelse(df$ht <= df$ht_cutoff, 1, 0)
如何使用来自基数 R 的 cut
:
sapply(c("F", "M"), function(s){
dfF <- df[df$sex==s,] # filter out per gender
cut(dfF$ht, breaks = c(0, mean(dfF$ht)-2*sd(dfF$ht), Inf), labels = c("low", "high"))
})
# dfF$ht heights per gender
# mean(dfF$ht)-2*sd(dfF$ht) cut point
在下面的代码中,我创建了 2 个新变量。两者都是通过对 sex
变量进行分组并过滤 ht
的不同范围而创建的。
library(dplyr)
df_low <- df %>% group_by(sex) %>% filter(ht<(mean(ht)-2*sd(ht)))
df_high<- df %>% group_by(sex) %>% filter(ht>(mean(ht)+2*sd(ht)))