根据变量获取列的值和位置
Get the value and position of column based on a variable
这是复制我的数据集的代码。
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)
我想获取大于 "check" column.If 可能的列的位置,我也想获取该列的值。
这是我创建的一个函数,它不起作用:
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)
如有任何帮助,我们将不胜感激。谢谢
我们可以使用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
和 MARGIN=1
遍历行,获取大于第 6 个值的元素 1 到 5 的数字索引,子集第一次出现([1]
,如果没有元素,这会自动将其转换为 NA)。基于此索引,我们对元素进行子集化、连接、获取转置并分配给 'df'.
中的新列
df[c('test', 'value')] <- t(apply(df, 1, function(x) {
i1 <- which(x[1:5]>x[6])[1]
c(i1, x[i1])}))
这是复制我的数据集的代码。
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)
我想获取大于 "check" column.If 可能的列的位置,我也想获取该列的值。
这是我创建的一个函数,它不起作用:
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)
如有任何帮助,我们将不胜感激。谢谢
我们可以使用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
和 MARGIN=1
遍历行,获取大于第 6 个值的元素 1 到 5 的数字索引,子集第一次出现([1]
,如果没有元素,这会自动将其转换为 NA)。基于此索引,我们对元素进行子集化、连接、获取转置并分配给 'df'.
df[c('test', 'value')] <- t(apply(df, 1, function(x) {
i1 <- which(x[1:5]>x[6])[1]
c(i1, x[i1])}))