【问题标题】:Change values from categorical to nominal in R在 R 中将值从分类更改为名义
【发布时间】:2017-03-21 21:41:40
【问题描述】:

我想按等级更改分类列中的所有值。可以使用列中已排序的唯一元素的索引来确定排名。

例如,

> data[1:5,1] 
[1] "B2" "C4" "C5" "C1" "B5"

然后我希望列中的这些条目替换分类值

> data[1:5,1]  
[1] "1" "4" "5" "3" "2"

另一栏:

> data[1:5,3]
[1] "Verified"        "Source Verified" "Not Verified"    "Source Verified" "Source Verified"

然后更新列:

> data[1:5,3]
[1] "3" "2" "1" "2" "2"

我在这个任务中使用了这段代码,但它需要很多时间。

for(i in 1:ncol(data)){
  if(is.character(data[,i])){
    temp <- sort(unique(data[,i]))
    for(j in 1:nrow(data)){
      for(k in 1:length(temp)){
        if(data[j,i] == temp[k]){
          data[j,i] <- k}
      }
    }
  }
}

如果可能的话,请建议我执行此操作的有效方法。 谢谢。

【问题讨论】:

  • 看看plyrs mapvalues

标签: r categorical-data columnname


【解决方案1】:

这是base R 中的一个解决方案。我创建了一个辅助函数,该函数将每列转换为一个因子,使用其唯一的排序值作为级别。这与您所做的类似,只是我使用as.integer 来获取排名值。

rank_fac <- function(col1) 
   as.integer(factor(col1,levels = unique(col1)))

一些数据示例:

dx <- data.frame(
  col1= c("B2" ,"C4" ,"C5", "C1", "B5"),
  col2=c("Verified"    ,    "Source Verified", "Not Verified"  ,  "Source Verified", "Source Verified")
)

在不使用 for 循环的情况下应用它。最好在此处使用lapply 以避免副作用。

data.frame(lapply(dx,rank_fac)

结果:

#       col1 col2
# [1,]    1    3
# [2,]    4    2
# [3,]    5    1
# [4,]    3    2
# [5,]    2    2

使用 data.table 语法糖

library(data.table)
setDT(dx)[,lapply(.SD,rank_fac)]
#    col1 col2
# 1:    1    3
# 2:    4    2
# 3:    5    1
# 4:    3    2
# 5:    2    2

更简单的解决方案:

仅使用as.integer

setDT(dx)[,lapply(.SD,as.integer)]

【讨论】:

  • 不错,但我认为data.frame(lapply(dx,rank_fac)replace(dx, , lapply(dx, rank_fac)) 甚至sapply(dx, rank_fac)do.call(cbind.. 更好
【解决方案2】:

使用match

# df is your data.frame    
df[] <- lapply(df, function(x) match(x, sort(unique(x))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 2013-03-16
    相关资源
    最近更新 更多