如何使用 R 检查数据一致性(确保大小写和值之间没有矛盾)



假设我有:

Person   Movie    Rating
Sally    Titanic  4
Bill     Titanic  4
Rob      Titanic  4
Sue      Cars     8
Alex     Cars     **9**
Bob      Cars     8

如您所见,亚历克斯存在矛盾。所有相同的电影都应该具有相同的排名,但亚历克斯有一个数据错误条目。如何使用 R 来解决此问题?我已经考虑了一段时间,但我无法弄清楚。我是否必须在 excel 或其他东西中手动执行此操作?R上是否有命令将返回两列之间存在数据矛盾的所有情况?

也许我可以让 R 做一个布尔检查,如果所有电影案例都与其第一次迭代的第一个评级匹配?对于所有返回"否"的内容,我可以手动查看吗?我将如何编写此函数?

谢谢

这是一个

data.table的解决方案

定义函数

Myfunc <- function(x) {
  temp <- table(x)  
  names(temp)[which.max(temp)]
}
library(data.table)

创建具有正确评级的列(通过引用)

setDT(df)[, CorrectRating := Myfunc(Rating), Movie][]
#    Person   Movie Rating CorrectRating
# 1:  Sally Titanic      4             4
# 2:   Bill Titanic      4             4
# 3:    Rob Titanic      4             4
# 4:    Sue    Cars      8             8
# 5:   Alex    Cars      9             8
# 6:    Bob    Cars      8             8

或者如果您想删除"差"评级

df[Rating == CorrectRating][]
#    Person   Movie Rating CorrectRating
# 1:  Sally Titanic      4             4
# 2:   Bill Titanic      4             4
# 3:    Rob Titanic      4             4
# 4:    Sue    Cars      8             8
# 5:    Bob    Cars      8             8

看起来,在"电影"定义的每个组中,您正在寻找与最常见值不同的任何评级实例。

您可以使用 dplyr(擅长"按一列分组,然后在每个组中执行操作")以及此答案中定义的"Mode"函数来解决此问题,该函数可在向量中找到最常见的项目:

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}
library(dplyr)
dat %>% group_by(Movie) %>% filter(Rating != Mode(Rating))

这将查找行与组的其余部分不一致的所有情况。如果您想删除它们,可以执行以下操作:

newdat <- dat %>% group_by(Movie) %>% filter(Rating == Mode(Rating))

如果要修复它们,请执行

newdat <- dat %>% group_by(Movie) %>% mutate(Rating = Mode(Rating))

您可以使用可重现的数据版本测试上述内容:

dat <- data.frame(Person = c("Sally", "Bill", "Rob", "Sue", "Alex", "Bob"),
                  Movie = rep(c("Titanic", "Cars"), each = 3),
                  Rating = c(4, 4, 4, 8, 9, 8))

如果目标是查看组中的所有值是否相同(或者是否存在一些差异),那么这可以是tapply(或aggregate等)的简单应用程序,与 var 等函数一起使用(或计算范围)。 如果所有值都相同,则方差和范围将为 0。 如果它是任何其他值(舍入误差之外),则必须有一个不同的值。 which功能可以帮助识别群体/个人。

tapply(dat$Rating, dat$Movie, FUN=var)
which(.Last.value > 0.00001)
tapply(dat$Rating, dat$Movie, FUN=function(x)diff(range(x)))
which(.Last.value != 0)
which( abs(dat$Rating - ave(dat$Rating, dat$Movie)) > 0)
which.max( abs(dat$Rating - ave(dat$Rating, dat$Movie)) )
dat[.Last.value,]
我会

为 mode 添加一个变量,这样我就可以查看数据是否有任何奇怪的情况,例如丢失数据、文本、许多不同的答案而不是罕见的异常等。我使用"x"作为您的数据集

# one of many functions to find mode, could use any other
modefunc <- function(x){
  names(table(x))[table(x)==max(table(x))]
}
# add variable for mode split by Movie
x$mode <- ave(x = x$Rating,x$Movie,FUN = modefunc)
# do whatever you want with the records that are different
x[x$Rating != x$mode, ]

如果您想要另一个模式函数,请尝试其他模式函数

最新更新