将多个变量组合成R中的新变量

时间:2015-05-21 17:10:58

标签: r if-statement cut

这可能对某些人来说非常简单,但我似乎无法让它适合我的生活。我尝试过使用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就是这个例子)。我有很多缺少的数据,我也需要报告。谢谢!

4 个答案:

答案 0 :(得分:2)

这个怎么样?

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] <- 0

答案 1 :(得分:2)

这是一种完全向量化的方法,随着数据集的增长,它可能比apply循环更快。这里可能的下降是我将零转换为NA s,因为它们都以相同的方式处理

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

您可以使用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)