以下是复制我的数据集的代码。
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)
任何帮助将不胜感激。感谢
答案 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]