R:使数据框中所有因子列中重复的水平唯一

潘曼

几天来,我一直困扰于R中的问题,试图使用循环使数据帧中多个因子列中的重复级别唯一。这是一个较大项目的一部分。

我有200多个SPSS数据集,其中案例数在4,000到23,000之间变化,变量数在120到1200之间变化(可以在这里找到其中一个SPSS数据集的摘录)。这些文件包含数字变量和因子变量,并且许多因子变量具有重复的级别。我已经使用了外部包中的数据包来导入它们,并保留了值标签,因为我需要它们作进一步的使用。在导入期间,R警告我有关因子列中重复的水平:read.spss

> adn <- read.spss("/tmp/adn_110.sav", use.value.labels = TRUE,
use.missings = TRUE, to.data.frame = TRUE)
Warning messages:
1: In read.spss("/tmp/adn_110.sav", use.value.labels = TRUE, use.missings = TRUE,  :
  /tmp/adn_110.sav: Unrecognized record type 7, subtype 18 encountered in system file
2: In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated
3: In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated

数据帧,导出为.RData可以在这里找到当我使用table(例如)获取任何因子列的每个级别的计数时,都会显示所有重复的级别,但是所有重复级别的计数都将添加到重复出现的第一个匹配项中,而对于所有其他水平,则返回0:

> table(adn[["adn01"]], useNA = "ifany")
  Incorrect         Incorrect Partially correct Partially correct 
          8                 0                 4                 0 
    Correct              <NA> 
          2                 1 
Warning message:
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated

我知道我可以轻松地as.numeric在致电时处理该因素table但是,我需要在输出中显示的级别名称。我可以make.unique使各个因子列的级别唯一,在重复级别的末尾附加一个数字:

> levels(adn[["adn01"]]) <- make.unique(levels(adn[["adn01"]]), sep = " ")

奇迹般有效。然后table告诉我正确的计数:

> table(adn[["adn01"]], useNA = "ifany")

          Incorrect         Incorrect 1   Partially correct 
                  5                   3                   1 
Partially correct 1             Correct                <NA> 
                  3                   2                   1 

但是,对200多个文件中的每个文件中的每个因子列执行此操作(变量数在120到1200之间变化)将是一生的任务。如果文件更改,我将必须重做所有操作。我天真地认为,遍历各个小室很容易。但是,make.table需要名称。我尝试了以下方法:

> lapply(adn[ , 1:length(adn)], make.unique(as.vector(attr(adn[ , 1:length(adn)],
"levels"))))
Error in make.unique(as.vector(attr(adn[, 1:length(adn)], "levels"))) : 
  'names' must be a character vector

没运气。在过去的几天里,我尝试了很多其他方法,包括经典for循环。仍然相同:'names' must be a character vector我猜问题出在索引levels的属性(这是一个列表组件)上,但是我不知道是什么。另一个问题可能是并非所有列都是因素有人可以帮忙吗?

编辑:

akrun提供的解决方案效果很好。再一次感谢你!

阿克伦

尝试

 load('adn.RData')
 indx <- sapply(adn, is.factor)
 adn[indx] <- lapply(adn[indx], function(x) {
                   levels(x) <- make.unique(levels(x))
                   x })


 table(adn[['adn01']], useNA='ifany')

 #     Incorrect         Incorrect.1   Partially correct Partially correct.1 
 #             5                   3                   1                   3 
 #       Correct                <NA> 
 #             2                   1 


  table(adn[['adn03']], useNA='ifany')

  #  Incorrect Partially correct           Correct              <NA> 
  #          6                 3                 5                 1 

更新

如果有多个文件,则可以将文件读入列表,然后在上进行处理list例如,考虑到文件位于工作目录中。

files <- list.files(pattern='^adn\\d+')
lst1 <- lapply(files, function(x) read.spss(x, use.value.labels = TRUE,
          use.missings = TRUE, to.data.frame = TRUE) #not tested

为了进行测试,我lst1使用相同的数据集进行创建adn

adn1 <- adn
lst1 <- list(adn, adn1)

现在,您make.unique为每个list元素应用

lst2 <- lapply(lst1, function(dat) {
                  indx <- sapply(dat, is.factor)
                  dat[indx] <- lapply(dat[indx], function(x){
                           levels(x) <- make.unique(levels(x))
                            x})
                          dat})


  lapply(lst2, function(x) table(x[['adn01']], useNA='ifany'))
  # [[1]]

  #    Incorrect         Incorrect.1   Partially correct Partially correct.1 
  #            5                   3                   1                   3 
  #      Correct                <NA> 
  #            2                   1 

  # [[2]]

  #    Incorrect         Incorrect.1   Partially correct Partially correct.1 
  #            5                   3                   1                   3 
  #      Correct                <NA> 
  #            2                   1 

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

查找数据框中所有列中唯一值的计数,不包括 NA 值 (R)

如何使数据框中的因子水平在所有列中保持一致?

更改 R 数据框中所有列中的值

如何提取列表中所有唯一因子水平的排列

如何获取R中该数据框中每一列的数据框中所有变量的计数信息?

数据框中的所有唯一列组合

如何遍历R中所有可能的因子水平比较

过滤/子集R中数据框中的所有因子

输出数据框中所有因子的级别数

扩展数据框以获得R中所有类别的唯一值的每月收入总和

如何将一列中所有值的数据框转换为多列中的数据框?

如何获取R中数据框中所有列的离群值

基于计数的数据帧中所有因子变量的折叠因子水平

从三列数据表中按名称返回所有因子水平作为新列。表[R]

将因子变量水平与较少的观察结果结合在一起。对于数据框中的所有因子变量

使具有重复值的列在数据框中唯一

如何基于R中的group_by函数对列中的所有唯一因子求和并输出为新列?

R枚举具有唯一值的数据框中的重复项

如何从某个特定列中的所有唯一值创建新的数据框列?

熊猫数据框中所有系列的唯一值计数的总计数

获取熊猫数据框中所有唯一行的计数

根据 R 中数据框中所有其他列中的字符串值,使用 dplyr 创建一个新列

查找数据框所有列的唯一值

如何在熊猫数据框中的所有列中获取唯一值

如何从数据框中删除等于R中单独数据框中唯一值的所有行?

对数据框列中的所有唯一值运行 Spicy.stats ANOVA 测试?

大熊猫数据框中所有列的基数/非重复计数

如何根据列对R中所有列的总和的贡献来删除数据框中的列

如何保留数据框中所有列中具有相同值的所有行?