假设我有下面的数据,我想添加列c,这样如果列b只包含正或负的值,我就有<0, 0, 0-3, >3
类别,否则列c中的类别将是b列所包含的任何类别。
df <- data.frame(a= 1:14,
b= c(-1,-10,-2,0,0,2,1,4,10,12,6, "apple", "apple", "Orange"))
df
a b
1 1 -1
2 2 -10
3 3 -2
4 4 0
5 5 0
6 6 2
7 7 1
8 8 4
9 9 10
10 10 12
11 11 6
12 12 apple
13 13 apple
14 14 Orange
df2
a b c
1 1 -1 <0
2 2 -10 <0
3 3 -2 <0
4 4 0 0
5 5 0 0
6 6 2 0-3
7 7 1 0-3
8 8 4 >3
9 9 10 >3
10 10 12 >3
11 11 6 >3
12 12 apple apple
13 13 apple apple
14 14 Orange Orange
我正在尝试应用case_when
和cut
。我得到了我需要的结果。我将非常感谢任何帮助和提示。
df %>%
mutate(c = case_when( b %in% grepl("apple|orange", b) ~ b),
TRUE ~ cut(as.numeric(b),
breaks = c(-999, 0, 1, 4, 999),
labels = c("<0", "0", "0-3", ">3"),
right = F))
最好将数字从非数字中提取出来,并分别进行处理。在base R
中,我们可以对每个
i1 <- grepl("^-?[0-9]+$", df$b)
df$c[i1] <- as.character(cut(as.numeric(df$b[i1]),
breaks = c(-999, 0, 1, 4, 999), labels = c("<0", "0", "0-3", ">3"), right = FALSE))
df$c[!i1] <- df$b[!i1]
与产出
> df
a b c
1 1 -1 <0
2 2 -10 <0
3 3 -2 <0
4 4 0 0
5 5 0 0
6 6 2 0-3
7 7 1 0-3
8 8 4 >3
9 9 10 >3
10 10 12 >3
11 11 6 >3
12 12 apple apple
13 13 apple apple
14 14 Orange Orange
如果我们想使用dplyr
library(dplyr)
df %>%
mutate(c = coalesce(case_when( !grepl("apple|orange", b) ~ as.character(cut(as.numeric(b),
breaks = c(-999, 0, 1, 4, 999),
labels = c("<0", "0", "0-3", ">3"),
right = FALSE))), b))
与产出
a b c
1 1 -1 <0
2 2 -10 <0
3 3 -2 <0
4 4 0 0
5 5 0 0
6 6 2 0-3
7 7 1 0-3
8 8 4 >3
9 9 10 >3
10 10 12 >3
11 11 6 >3
12 12 apple apple
13 13 apple apple
14 14 Orange Orange
注意:case_when
或ifelse
对整个数据应用函数,所以当我们执行as.numeric
时,非数字元素被强制到NA
,因此第一个选项被覆盖。相反,使用replace
或coalesce
,b
列在case_when