我有一个数据框,其中的一列包含不同的颜色。我的目的是计算此列中有多少种不同的颜色。注意:“红色,1”,“ 1红色”,“红色2”都是红色,因此以上所有仅算为一种颜色。但是,“深红色”是不同的颜色
Item Color
Flower Red 1
Flower Yellow 1
Flower Red, 1
Flower Red 2
Flower 2 red
Flower Green, 1
Flower Dark Red 1
Flower Green, 2
Flower Black
Flower White 1
Flower 1A, Green
因为在此列中,颜色名称的结构不同。因此,我不能仅仅使用sub()删除第一个单词之后的所有内容并计算数量。我尝试使用sapply(apply())或grep()进行近似匹配,但结果并不理想。我还尝试了distinct()保留所有唯一的颜色名称,但是它无法处理诸如“ Red,1”和“ Red,2”之类的字符串对我来说,最困难的情况是颜色后面带有逗号,例如“ 1A,蓝色”或其他]
我希望结果可以是
Flower Red
Flower Yellow
Flower Green
Flower Dark Red
Flower Black
Flower White
或更简单
6
不需要循环,*apply
或其他,适当的正则表达式将完成大部分工作。
x <- tolower(gsub("[^[:alpha:]]", "", flowers$Color))
unique(x)
#[1] "red" "yellow" "green" "black" "white"
length(unique(x))
#[1] 5
数据。
flowers <- read.table(text = "
Item Color
Flower 'Red 1'
Flower 'Yellow 1'
Flower 'Red, 1'
Flower 'Red 2'
Flower '2 red'
Flower 'Green, 1'
Flower 'Green, 2'
Flower 'Black'
Flower 'White 1'
", header = TRUE, stringsAsFactors = FALSE)
[C0的选项
dplyr
library(stringr)
library(dplyr)
flowers %>%
summarise(len = n_distinct(Item, tolower(str_remove(Color, "[^A-Za-z]+"))))
# len
#1 5
使用 flowers <- structure(list(Item = c("Flower", "Flower", "Flower", "Flower",
"Flower", "Flower", "Flower", "Flower", "Flower"), Color = c("Red 1",
"Yellow 1", "Red, 1", "Red 2", "2 red", "Green, 1", "Green, 2",
"Black", "White 1")), class = "data.frame", row.names = c(NA,
-9L))
软件包和stringr
的另一种解决方案。
colors()
输出:
library(readr)
library(stringr)
A <- read_table("Item Color
Flower Red 1
Flower Yellow 1
Flower Red, 1
Flower Red 2
Flower 2 red
Flower Green, 1
Flower Green, 2
Flower Black
Flower White 1")
A$Color <- casefold(A$Color, upper = TRUE)
colors_considered <- casefold(colors(), upper = TRUE)
bb <- as.data.frame(A$Color)
BB <- apply(bb,1,function(x) str_extract(x,colors_considered))
CC <- BB[!is.na(BB)]
output <- data.frame(item = A$Item,color = CC) %>%
unique()
假设数据帧称为> output
item color
1 Flower RED
2 Flower YELLOW
6 Flower GREEN
8 Flower BLACK
9 Flower WHITE
,则可以使用:
df
说明:
length(unique(toupper(gsub("[^a-zA-Z]", "", df$Color))))
删除所有非字符的内容。因此,您只剩下颜色。
gsub("[^a-zA-Z]", "", df$Color)
大写剩余的文本,而unique则删除重复项。 toupper
为您提供向量中元素的数量。您将得到length
。
Addition:要处理“红色,1A”的情况,您可以删除','之后的所有内容,然后使用上述解决方案。例如:
5
x <- gsub(",.*$", "", df$Color) ## removes a comma and anything that follows
Alternative删除逗号后的所有内容:您可以使用以下方式删除任何字母数字,例如“ 1A”或“ A1”:
length(unique(toupper(gsub("[^a-zA-Z]", "", x)))) ## removes all but letters