将新值分配给R中的级别

时间:2017-09-23 01:50:36

标签: r dataframe levels

所有

我有一个大型数据集(超过200万行),在其中一个列中我有以下级别:

"0"     "0.001" "1"     "4"     "4.001" "8.001"

我想创建一个新列,其中每个列都有一个新的相应字母:

0 = x,0.001 = D,1 = C,4和4.001 = B,和8.001 = A

有没有办法在不使用带有6个if语句的for循环的情况下执行此操作?我试过了,它一直在运行。

这是一个测试样本:

      a b
1 0.000 x
2 4.000 B
3 1.000 C
4 0.001 D
5 1.000 C
6 4.000 B
7 4.001 B
8 1.000 C
9 8.001 A

谢谢。

4 个答案:

答案 0 :(得分:2)

最简单的方法是创建一个键/值数据集并与原始数据连接

keyval <- data.frame(a = c(0, 0.001, 1, 4, 4.001, 8.001), 
     b = c('x', 'D', 'C', 'B', 'B', 'A'), stringsAsFactors= FALSE)
library(data.table)
setDT(df1)[keyval, b := b, on = .(a)]
df1
#       a b
#1: 0.000 x
#2: 4.000 B
#3: 1.000 C
#4: 0.001 D
#5: 1.000 C
#6: 4.000 B
#7: 4.001 B
#8: 1.000 C
#9: 8.001 A

数据

df1 <- structure(list(a = c(0, 4, 1, 0.001, 1, 4, 4.001, 1, 8.001)), 
    .Names = "a", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9"), class = "data.frame")

答案 1 :(得分:1)

我不相信有一个单行命令可以为你做。 BTW for循环本质上是低效的,不推荐用于大型数据集。

选项1:
您可能想要尝试的是logical indexing,这是bit array的统计实现。

idx<- df$a == "0.000"
df$NewColumn[idx] <- "x"

idx<- df$a == "4.000"
df$NewColumn[idx] <- "B"

依旧等等......

选项2:
使用plyrrevalue这是一个更简单的实现,但可能比选项1更加计算密集。应该仍然可以轻松地适应您的数据大小。

library(plyr)
df$NewColumn <- revalue(df$a, c(0 = "x", 0.001 = "D", 1 = "C", 4 = "B", 4.001 = "B", and 8.001 = "A"))

对于任一选项,请确保正确提供数据类型class。从您的示例中,我很难判断数据是factor还是numeric,但无论如何,它都是我在示例代码中进行管理的简单更改。

答案 2 :(得分:0)

尝试as.factor(x,levels = c(用逗号分隔的任何级别和值))

答案 3 :(得分:0)

我会尝试这个,但不是关于运行时的确定:

library(forcats)
df = data.frame(a = c("0", "0.001", "1", "4", "4.001", "8.001"))
df$b <- fct_recode(df$a,
               X = "0",
               D = "0.001",
               C = "1",
               B = "4",
               B = "4.001",
               A = "8.001")

enter image description here