【问题标题】:Converting numeric values to factor levels with factor levels assigned on the basis of the numeric ordering将数值转换为因子水平,并根据数字排序分配因子水平
【发布时间】:2017-07-18 09:26:12
【问题描述】:

考虑数据框

a = c(0, 1, 3, 5, 6, 0, 1, 3, 6, 12)
b = c(letters[5:9], letters[2:6])
c = data.frame(var1 = a, var2 = b)

我想将数据框中的所有值转换为从1 开始的连续整数因子级别,并将这些值用作数值来计算某些东西(实际上我不会为字母执行此操作,但我只是将这些添加到解释我的问题;))。

在一些帮助 (Converting numeric values of multiple columns to factor levels that are consecutive integers in (descending) order) 的帮助下,我做到了:

c[] = lapply(c, function(x) {levels(x) <- 1:length(unique(x)); x})

不幸的是,这仅将值替换为charactervar2 的值,而不是numericvar1 的值(注意0var1

> c
   var1 var2
1     0    4
2     1    5
3     3    6
4     5    7
...

为了缓解这个问题,我在创建c时将所有列都转换为字符

c = as.data.frame(sapply(data.frame(var1 = a, var2 = b), as.character))

这会产生

   var1 var2
1     1    4
2     2    5
3     4    6
4     5    7
5     6    8
6     1    1
7     2    2
8     4    3
9     6    4
10    3    5

然而,这里的问题是var1 列中的值12 (c[10,'var1']) 被视为第三个值(它在12 级别之后被分配因子级别3对于值01)而不是最后一个值(因子级别6,因为它是var1 中的最大数值)。

有没有办法根据数值排序来分配因子水平,同时用它们的因子水平替换数值?

【问题讨论】:

  • 我刚刚找到了一种方法,通过c = data.frame(var1 = str_pad(a, 2, pad = "0"), var2 = b) 向一位数字添加零。有没有更清洁的解决方案?

标签: r


【解决方案1】:

根据描述,OP 似乎想将 levels 更改为从 1 开始的数值。这可以使用 match 来完成

c[] <- lapply(c, function(x) factor(match(x, sort(unique(x)))))
c
#    var1 var2
#1     1    4
#2     2    5
#3     3    6
#4     4    7
#5     5    8
#6     1    1
#7     2    2
#8     3    3
#9     5    4
#10    6    5

数据

a <- c(0, 1, 3, 5, 6, 0, 1, 3, 6, 12)
b <- c(letters[5:9], letters[2:6])
c <- data.frame(var1 = a, var2 = b)

根据 cmets 中的代码,替换 str_pad 的另一个选项是

c <- data.frame(var1 = sprintf("%02d", a), var2=b, stringsAsFactors=FALSE)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-19
    • 2015-01-27
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2018-12-07
    相关资源
    最近更新 更多