如何使用R来检查数据的一致性(确保案例和值之间没有矛盾)?

时间:2014-12-13 20:11:49

标签: r data-cleaning

我们说我有:

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

正如你所看到的,亚历克斯存在矛盾。所有相同的电影应该具有相同的排名,但Alex有一个数据错误条目。我怎样才能用R来解决这个问题?我已经考虑了一段时间,但我无法弄明白。我是否必须在Excel中手动执行此操作?在R上是否有一个命令可以返回两列之间存在数据矛盾的所有情况?

如果所有Movie案例都匹配第一次迭代的第一个评级,也许我可以让R做一个布尔检查?对于所有返回"不,"我可以手动看一下吗?我该怎么写这个函数?

由于

4 个答案:

答案 0 :(得分:4)

这是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

或者如果你想删除&#34;坏&#34;评分

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

答案 1 :(得分:2)

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

您可以使用dplyr(擅长&#34;按一列分组,然后在每个组内执行操作)以及&#34;模式&#34;来解决此问题。函数defined in this answer,用于查找向量中最常见的项目:

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))

答案 2 :(得分:1)

如果目标是查看组中的所有值是否相同(或者是否存在某些差异),那么这可以是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,]

答案 3 :(得分:0)

我会为模式添加一个变量,这样我就可以看到数据是否有任何奇怪的现象,比如缺少数据,文本,许多不同的答案,而不是罕见的异常等。我使用&#34; x&#34;作为您的数据集

# 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, ]

如果您想要其他模式功能,请尝试other functions for mode