按组用不同的切点进行变异
Mutate with different cut points by group
我想为不同的组切割一个具有不同切割点的数值变量。
我试过组合成一个列表,但我怀疑我需要一些函数和循环的组合。可以找到类似的重新编码示例 here,但 cut 不接受列表。
有什么建议吗?
可以扩展成宽格式,但我想知道如何在长格式中执行此操作。
Cutpoints1<-c(0,1,10,100,9999)
Cutpoints2<-c(0,10,20,50,100,9999)
Cutpoints1<-c(0,1,10,100,9999)
Cutpoints<-list(Cutpoints1, Cutpoints2)
Df2<-Df1 %>%
group_by(group) %>%
mutate(varcat=cut(var,Cutpoints))
如果你指的是基数 R cut
(这在上下文中有意义),你可以使用几种不同的方法,这取决于你的组变量是如何编码的以及你想要输入多少与转换多少做。 (很难说什么是最好的,因为您还没有向我们展示您的数据是什么样的。)
library(tidyverse)
Cutpoints2<-c(0,10,20,50,100,9999)
Cutpoints1<-c(0,1,10,100,9999)
test = tibble(
numbers = seq(from = 0, 99.5, by = 0.5),
group = rep(c(1,2),length(numbers)/2)
)
## Method 1: ifelse
test %>%
group_by(group) %>%
mutate(cut_group =
ifelse(group == 1,
cut(numbers, Cutpoints1) %>% as.character,
cut(numbers, Cutpoints2) %>% as.character)
)
## Method 2: get
test %>%
group_by(group) %>%
mutate(cut_group =
cut(numbers,
get(paste0("Cutpoints",group))) %>% as.character
)
如果您只有几个分割点,那么 ifelse
方法是一种调用 cut
的简单方法,通过手动引用每个分割点向量来注释您的行。必须调用as.character
因为cut产生的因子发挥不好。 (也可能有一种方法可以在函数中去掉它,但是 as.character
在任何情况下都有效。)但是,如果你有很多分割点,你可以使用 get
来获取作为字符串传递的变量的值,我在这里用 paste0
构造它——如果你将它们编码为 "group1" 或其他东西,你可以 stringr::str_replace_all
。
在任何一种情况下,您都可以使用我创建的测试小标题得到这个结果:
# A tibble: 200 x 3
# Groups: group [2]
numbers group cut_group
<dbl> <dbl> <chr>
1 0 1 NA
2 0.5 2 (0,10]
3 1 1 (0,1]
4 1.5 2 (0,10]
5 2 1 (1,10]
6 2.5 2 (0,10]
7 3 1 (1,10]
8 3.5 2 (0,10]
9 4 1 (1,10]
10 4.5 2 (0,10]
# … with 190 more rows
如果您已经在向量列表中拥有所有的分割点,您只需使用 Cutpoints[[paste0("Cutpoints",group)]]
来调用它们,而不是使用 get
。否则,没有必要将它们包装在列表中。
我想为不同的组切割一个具有不同切割点的数值变量。
我试过组合成一个列表,但我怀疑我需要一些函数和循环的组合。可以找到类似的重新编码示例 here,但 cut 不接受列表。
有什么建议吗?
可以扩展成宽格式,但我想知道如何在长格式中执行此操作。
Cutpoints1<-c(0,1,10,100,9999)
Cutpoints2<-c(0,10,20,50,100,9999)
Cutpoints1<-c(0,1,10,100,9999)
Cutpoints<-list(Cutpoints1, Cutpoints2)
Df2<-Df1 %>%
group_by(group) %>%
mutate(varcat=cut(var,Cutpoints))
如果你指的是基数 R cut
(这在上下文中有意义),你可以使用几种不同的方法,这取决于你的组变量是如何编码的以及你想要输入多少与转换多少做。 (很难说什么是最好的,因为您还没有向我们展示您的数据是什么样的。)
library(tidyverse)
Cutpoints2<-c(0,10,20,50,100,9999)
Cutpoints1<-c(0,1,10,100,9999)
test = tibble(
numbers = seq(from = 0, 99.5, by = 0.5),
group = rep(c(1,2),length(numbers)/2)
)
## Method 1: ifelse
test %>%
group_by(group) %>%
mutate(cut_group =
ifelse(group == 1,
cut(numbers, Cutpoints1) %>% as.character,
cut(numbers, Cutpoints2) %>% as.character)
)
## Method 2: get
test %>%
group_by(group) %>%
mutate(cut_group =
cut(numbers,
get(paste0("Cutpoints",group))) %>% as.character
)
如果您只有几个分割点,那么 ifelse
方法是一种调用 cut
的简单方法,通过手动引用每个分割点向量来注释您的行。必须调用as.character
因为cut产生的因子发挥不好。 (也可能有一种方法可以在函数中去掉它,但是 as.character
在任何情况下都有效。)但是,如果你有很多分割点,你可以使用 get
来获取作为字符串传递的变量的值,我在这里用 paste0
构造它——如果你将它们编码为 "group1" 或其他东西,你可以 stringr::str_replace_all
。
在任何一种情况下,您都可以使用我创建的测试小标题得到这个结果:
# A tibble: 200 x 3
# Groups: group [2]
numbers group cut_group
<dbl> <dbl> <chr>
1 0 1 NA
2 0.5 2 (0,10]
3 1 1 (0,1]
4 1.5 2 (0,10]
5 2 1 (1,10]
6 2.5 2 (0,10]
7 3 1 (1,10]
8 3.5 2 (0,10]
9 4 1 (1,10]
10 4.5 2 (0,10]
# … with 190 more rows
如果您已经在向量列表中拥有所有的分割点,您只需使用 Cutpoints[[paste0("Cutpoints",group)]]
来调用它们,而不是使用 get
。否则,没有必要将它们包装在列表中。