有条件地转换R数据帧中的数字

时间:2016-01-27 00:29:30

标签: r dataframe

我正在尝试转换数据,以便每个列都由0,1和2表示。我有一个包含5个种群和6个变量的数据框(实际数据框中实际上有100多个种群和5,000多个变量):

               pop      Var1    Var2    Var3     Var4     Var5     Var6 
1           Crater      11      11      22       44       11       22       
2            Teton      14      44      12       34       33       22       
3      Vipond Park      44      11      22       44       33       NA       
4       Little Joe      11      44      NA       44       13       44       
5          Rainier      14      11      11       NA       11       44       

在每一栏中,我有以下数字组合: 1和3, 2和4, 2和3, 1和4, 3和4, 1和2

对于每一列,我需要将“doubled numbers”中的一个转换为0,将doubled数字中的OTHER转换为2,然后将那两个数字组合的变量转换为1(中间值) )。 (所以,13,24,23,14,34和12应该变成1。)

例如,对于上面数据框中的Var1,11应该是0,14应该是1,444应该是2.有些列只有一个加倍的数字,然后是数字的组合。还有数据丢失。例如,我正在尝试将上述数据框转换为:

               pop      Var1    Var2    Var3     Var4     Var5     Var6 
1           Crater      0       0       0        0        0        0       
2            Teton      1       2       1        1        2        0       
3      Vipond Park      2       0       0        0        2        NA       
4       Little Joe      0       2       NA       0        1        2       
5          Rainier      1       0       2        NA       0        2  

1 个答案:

答案 0 :(得分:3)

u成为x中唯一的非NA元素。 is.twice是一个逻辑向量,对于u中的两位数为TRUE,对于u中的非双位数为FALSE。 uu是唯一的两位数,other是剩余数字,如果没有其他数字,则长度可以为零。最后计算与labels相关联的c(uu, other)并执行x的翻译:

f <- function(x) {   

   u <- unique(na.omit(x))

   # separate u into uu (double digits) and other
   is.twice <- u %% 10 == u %/% 10 # true if double digit
   uu <- u[is.twice]
   other <- u[!is.twice]

   # compute labels associated with c(uu, other)
   labels <- c(0, 2)[seq_along(uu)]
   if (length(other) > 0) labels <- c(labels, 1)

   # translate x to appropriate labels
   labels[match(x, c(uu, other))]

}

replace(DF, -1, lapply(DF[-1], f))

对于样本数据给出:

          pop Var1 Var2 Var3 Var4 Var5 Var6
1      Crater    0    0    0    0    0    0
2       Teton    1    2    1    1    2    0
3 Vipond Park    2    0    0    0    2   NA
4  Little Joe    0    2   NA    0    1    2
5     Rainier    1    0    2   NA    0    2

注意:上面使用了这个输入:

DF <- 
structure(list(pop = structure(c(1L, 4L, 5L, 2L, 3L), .Label = c("Crater", 
"Little Joe", "Rainier", "Teton", "Vipond Park"), class = "factor"), 
    Var1 = c(11L, 14L, 44L, 11L, 14L), Var2 = c(11L, 44L, 11L, 
    44L, 11L), Var3 = c(22L, 12L, 22L, NA, 11L), Var4 = c(44L, 
    34L, 44L, 44L, NA), Var5 = c(11L, 33L, 33L, 13L, 11L), Var6 = c(22L, 
    22L, NA, 44L, 44L)), .Names = c("pop", "Var1", "Var2", "Var3", 
"Var4", "Var5", "Var6"), class = "data.frame", row.names = c(NA, 
-5L))

更新:已修复。