从重复的因子水平清除角色观察

时间:2017-03-29 16:05:50

标签: r concatenation levels

情况如下:我有一个列为“a”的列字符,包含许多整数。每个整数代表一个类别。我想知道每个观察它们包含哪些独特的水平。 列b表示所需的结果:清除重复项,但表示每个唯一级别。 我想知道的是如何清理a列,使其看起来像b列。我需要将解决方案实现到60k行。

                                                       a          b
1 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5 |   4, 5
2                            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 |   2
3           86, 86, 86, 86, 86, 37, 37, 37, 37, 37, 37, 8, 8 |   86, 37, 8   

a <- c("4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5", "2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2", "86, 86, 86, 86, 86, 37, 37, 37, 37, 37, 37, 8, 8")
b <- c("4, 5", "2", "86, 37, 8")
df <- data.frame(a, b)

我已经阅读了一些关于删除重复因子值的帖子,但是你可以尝试自己,这不会产生任何有用的东西。

droplevels(factor(df$a))

这基本上解决了这个问题,但对于60k行是不可行的。

df$a[1] <- factor(unique(as.numeric(unlist(str_extract_all(df$a[1], "[[:digit:]]+")))))
df$a[2] <- factor(unique(as.numeric(unlist(str_extract_all(df$a[2], "[[:digit:]]+")))))
df$a[3] <- factor(unique(as.numeric(unlist(str_extract_all(df$a[3], "[[:digit:]]+")))))

1 个答案:

答案 0 :(得分:3)

你错过了sapply在这里的使用。这可以防止你不得不按元素构造元素,例如:

df$a <- sapply(a,function(i){
  paste(unique(strsplit(i,", ")[[1]]),
        collapse = ", ")
})

df$a
#> [1] "4, 5"      "2"         "86, 37, 8"

请记住,strsplit()适用于角色向量。因此,在构造数据时使用stringsAsFactors = FALSE,或者使用as.character()将因子变量首先转换为字符。在我的代码中,我只使用向量a

旁注:我喜欢stringr包,但在这种情况下,strsplit()会为您提供更快的代码。使用上面的代码,可以避免使用正则表达式创建的大量开销。