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