根据变量

时间:2015-10-05 18:32:12

标签: r function conditional apply

以下是复制我的数据集的代码。

col1=c(20,15,NA,NA)
col2=c(30,30,6,NA)
col3=c(40,NA,7,NA)
col4=c(NA,60,8,NA)
col5=c(60,75,9,NA)
check=c(40,35,10,NA)

df=data.frame(col1,col2,col3,col4,col5,check)

我想得到的列的位置大于"检查"如果可能的话,我也希望获得该列的值。

这是我创建的一个功能,它不起作用:

fun=function(x){
        j1=which(x>df$check)[1]
        if(is.na(j1)){
                NA
        }
        else if (!is.na(j1)){
                j1
        }
}

df$test=apply(df[,1:5],1,fun)

我的最终数据框架如下所示:

col1=c(20,15,NA,NA)
col2=c(30,30,6,NA)
col3=c(40,NA,7,NA)
col4=c(NA,60,8,NA)
col5=c(60,75,9,NA)
check=c(40,35,10,NA)
test=c(5,4,NA,NA)
value=c(60,60,NA,NA)
df=data.frame(col1,col2,col3,col4,col5,check, test,value)

任何帮助将不胜感激。感谢

1 个答案:

答案 0 :(得分:2)

我们可以使用max.col来获取列索引。使用行序列和列索引,我们可以从前五列中提取元素。

#created a logical matrix
m1 <- df[1:5] > df$check
#changed the NA elements to FALSE
m1[is.na(m1)] <- FALSE
#used max.col to get the column index.  For rows that have all FALSE
#we change it to 0 after multiplying with the logical index of `rowSums(..`.
v1 <- max.col(m1, 'first')*(rowSums(m1)!=0)
#reconvert the 0 values to NA
test <-  NA^(v1==0)*v1
#extract the elements using row/column index
value <- df[1:5][cbind(1:nrow(df), test)]
#cbind the new vectors to get the desired output.
df <- cbind(df, test, value)
df
#   col1 col2 col3 col4 col5 check test value
#1   20   30   40   NA   60    40    5    60
#2   15   30   NA   60   75    35    4    60
#3   NA    6    7    8    9    10   NA    NA
#4   NA   NA   NA   NA   NA    NA   NA    NA

或者可以使用apply创建两个列。虽然这可能是紧凑的,但与第一个解决方案相比可能效率较低。我们使用带有apply的{​​{1}}遍历行,获取大于第6个值的元素1到5的数字索引,第一个出现的子集(MARGIN=1,如果没有元素,这将自动将其转换为NA)。基于此索引,我们对元素进行子集化,连接,获取转置并分配给'df'中的新列。

[1]