【问题标题】:Combing multiple variables into a new variable in R在R中将多个变量组合成一个新变量
【发布时间】:2015-05-21 17:10:58
【问题描述】:

这对某人来说可能很简单,但我似乎无法让它为我的生活服务。我试过使用 cut 和 ifelse 但我得到的关卡没有我想要的值。任何想法将不胜感激。这是一些假数据:

 o5<-c(1,0,2,0,0,NA)
 o6<-c(NA,0,NA,2,0,NA)
 o7<-c(0,0,NA,2,2,1)
 ID<-seq(1,6,1)
 d1<-cbind(ID,o5,o6,o7)

     ID o5 o6 o7
[1,]  1  1 NA  0
[2,]  2  0  0  0
[3,]  3  2 NA NA
[4,]  4  0  2  2
[5,]  5  0  0  2
[6,]  6 NA NA  1

我正在尝试将 o5,o6,o7 组合成一个 o_all 变量,如下所示:

     ID o5 o6 o7 o_all
[1,]  1  1 NA  0  5
[2,]  2  0  0  0  0
[3,]  3  2 NA NA  5
[4,]  4  0  2  2  6
[5,]  5  0  0  2  7
[6,]  6 NA NA  1  7

每个 o 变量表示学生的年级水平。如果他们对该等级有一个非零值,他们应该在 o_all 中获得等级级别的值(这是见证特定行为开始的等级)。如果它们表示两个或多个等级,那么我选择最早的值(ID #4 就是一个例子)。我也有很多缺失的数据需要计算。谢谢!

【问题讨论】:

  • 这些都对我有用,只需稍作调整。谢谢!

标签: r if-statement cut


【解决方案1】:

这个呢?

res <- cbind(d1,o_all = as.numeric(gsub("[^0-9]", "", colnames(d1[,-1]))[apply(d1[,-1], 1, function(x) which((x!=0))[1])]))
res
     ID o5 o6 o7 o_all
[1,]  1  1 NA  0     5
[2,]  2  0  0  0    NA
[3,]  3  2 NA NA     5
[4,]  4  0  2  2     6
[5,]  5  0  0  2     7
[6,]  6 NA NA  1     7

然后您可以将NA 替换为0,例如通过res[is.na(res[, 5]),5] &lt;- 0

【讨论】:

    【解决方案2】:

    这是一种完全矢量化的方法,随着数据集的增长,它可能比apply 循环更快。这里可能的原因是我也将零转换为NAs,因为它们的处理方式相同

    is.na(d1) <- d1 == 0L
    indx <- (rowSums(is.na(d1)) == (ncol(d1) - 1L)) + 1L
    max.col(!is.na(d1[, -1L]), ties.method = "first") + c(4L, -1L)[indx]
    ## [1] 5 0 5 6 7 7
    

    【讨论】:

      【解决方案3】:
      d1 <- cbind(d1, o_all = apply(d1[, -1], 1, function(x) {
        i <- which.max(!is.na(x) & x > 0) 
        if(x[i] == 0) 0 else i + 4
      }))
      #     ID o5 o6 o7 o_all
      #[1,]  1  1 NA  0     5
      #[2,]  2  0  0  0     0
      #[3,]  3  2 NA NA     5
      #[4,]  4  0  2  2     6
      #[5,]  5  0  0  2     7
      #[6,]  6 NA NA  1     7
      

      【讨论】:

        【解决方案4】:

        您可以使用apply 遍历每一行,选择具有最大值的列:

        result <- apply(d1,1,function(row){which.max(row[2:length(row)])})
        

        请注意,我使用row[2:length(row)] 来排除ID 列。 这会给你一个类似的结果:

        > result
        [1] 1 1 1 2 3 3
        

        您可以使用它来分配给您的o_all 列:

        o_all <- as.numeric(gsub("[^0-9]", "",colnames(d1)[result+1]))
        cbind(d1,o_all)
        

        【讨论】:

        • 第二个条目与您的方法不正确
        猜你喜欢
        • 2018-10-23
        • 2021-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-13
        相关资源
        最近更新 更多