删除重复项时计数的R函数

R function for count number while deleting the duplicates

我有一个数据框,其中有一列包含不同的颜色。我的目的是计算此列中有多少种不同的颜色。注:"Red, 1"、"1 Red"、"Red 2"都是红色,所以以上只算一种颜色。但是,"Dark Red" 是不同的颜色

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, Blue”或者别的什么

希望结果可以

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)

假设数据帧名为 df 那么您可以使用:

length(unique(toupper(gsub("[^a-zA-Z]", "", df$Color))))

解释:

gsub("[^a-zA-Z]", "", df$Color) 删除任何非字符的内容。所以你只剩下颜色了。

toupper将剩余的文本大写,unique 去除重复。 length 给出向量中元素的数量。你会得到5.

Addition: 要处理"Red, 1A" 的情况,您可以删除',' 之后的所有内容,然后使用上述解决方案。例如:

x <- gsub(",.*$", "", df$Color) ## removes a comma and anything that follows

length(unique(toupper(gsub("[^a-zA-Z]", "", x)))) ## removes all but letters

替代方法 删除逗号后的所有内容:您可以使用以下方法删除任何字母数字,例如“1A”或 "A1":

x <- gsub("[a-zA-Z]*[0-9][a-zA-Z]*", "", df$Color)

选项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