按彼此百分比的值对变量进行分组
Group variables by values with % of each other
我想对 df 的行进行分组,其中某一列的值彼此相差 x%。
例如,在以下 df 中,10% 的值差异将分为 3 组:(A、C、F)、(B、D)、(E)。
所以某种分组依据的值有 +/- 10% 的变化。
tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))
作为一个快速而肮脏的解决方案,我建议:
library(tidyverse)
df <- tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))
df %>%
mutate(group = ceiling((value/max(value))/0.1))
您可以在其中改变 0.1
除数。
像这样的东西会起作用。 “组”就是 Item.
您可以看到,由于您指定的方式,会有很多边缘情况。您可以删除参数 mult = "first" 来解析它们。
dt <- data.table(tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99)))
dt[, `:=`(lower_bound = value * .9,
upper_bound = value * 1.1)]
dt[dt, on = .(value > lower_bound,
value < upper_bound), mult = "first"][, .(i.Item), Item]
# Item i.Item
# 1: A A
# 2: A C
# 3: A F
# 4: B B
# 5: B D
# 6: E E
既然你在评论中阐明了顺序元素不会相互冲突,你可以这样做
library(dplyr)
df %>% arrange(value) %>%
group_by(grp = cumsum(lag(value, default = 0)*1.1 <= value)) %>%
ungroup() %>%
arrange(Item)
# A tibble: 6 x 3
Item value grp
<chr> <dbl> <int>
1 A 1.01 1
2 B 2.42 2
3 C 1.03 1
4 D 2.45 2
5 E 3.1 3
6 F 0.99 1
如果 value
中可能存在负值,这也会产生预期的结果
df %>% arrange(value) %>%
group_by(grp = 1 + cumsum(lag(value, default = first(value))*1.1 <= value)) %>%
ungroup() %>%
arrange(Item)
# A tibble: 6 x 3
Item value grp
<chr> <dbl> <dbl>
1 A 1.01 1
2 B 2.42 2
3 C 1.03 1
4 D 2.45 2
5 E 3.1 3
6 F 0.99 1
我想对 df 的行进行分组,其中某一列的值彼此相差 x%。 例如,在以下 df 中,10% 的值差异将分为 3 组:(A、C、F)、(B、D)、(E)。 所以某种分组依据的值有 +/- 10% 的变化。
tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))
作为一个快速而肮脏的解决方案,我建议:
library(tidyverse)
df <- tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))
df %>%
mutate(group = ceiling((value/max(value))/0.1))
您可以在其中改变 0.1
除数。
像这样的东西会起作用。 “组”就是 Item.
您可以看到,由于您指定的方式,会有很多边缘情况。您可以删除参数 mult = "first" 来解析它们。
dt <- data.table(tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99)))
dt[, `:=`(lower_bound = value * .9,
upper_bound = value * 1.1)]
dt[dt, on = .(value > lower_bound,
value < upper_bound), mult = "first"][, .(i.Item), Item]
# Item i.Item
# 1: A A
# 2: A C
# 3: A F
# 4: B B
# 5: B D
# 6: E E
既然你在评论中阐明了顺序元素不会相互冲突,你可以这样做
library(dplyr)
df %>% arrange(value) %>%
group_by(grp = cumsum(lag(value, default = 0)*1.1 <= value)) %>%
ungroup() %>%
arrange(Item)
# A tibble: 6 x 3
Item value grp
<chr> <dbl> <int>
1 A 1.01 1
2 B 2.42 2
3 C 1.03 1
4 D 2.45 2
5 E 3.1 3
6 F 0.99 1
如果 value
df %>% arrange(value) %>%
group_by(grp = 1 + cumsum(lag(value, default = first(value))*1.1 <= value)) %>%
ungroup() %>%
arrange(Item)
# A tibble: 6 x 3
Item value grp
<chr> <dbl> <dbl>
1 A 1.01 1
2 B 2.42 2
3 C 1.03 1
4 D 2.45 2
5 E 3.1 3
6 F 0.99 1