我有一个如下所示的数据集(nm),其中前三列显示用户是否使用该产品,即1(是)或0(不)。接下来的三列显示了A_TT与A_TT_1.1对应的产品的喜好百分比,同样如下:
nm
A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1
0 0 1 0.06 0.84 0.89
1 1 0 0.92 0.83 0.94
0 1 0 0.09 0.9 0.13
1 0 1 0.87 0.05 0.9
0 0 0 0.13 0.11 0.14
我想在数据集(nm)中添加两列,即Rank1&排名2,排名前两位有以下两个条件:
a)仅在前三列中值为“零”的位置进行选择和排名 b)在排名列中,它应该返回其列名。
最终输出应为:
nm
A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1 Rank 1 Rank 2
0 0 1 0.06 0.84 0.89 B_TT_2.1 A_TT_1.1
1 1 0 0.92 0.83 0.94 C_TT_3.1 NONE
0 1 0 0.09 0.9 0.13 C_TT_3.1 A_TT_1.1
1 0 1 0.87 0.05 0.9 B_TT_2.1 NONE
0 0 0 0.13 0.11 0.14 C_TT_3.1 A_TT_1.1
我尝试了很多选项,但没有任何效果。提前感谢您提供解决方案。
答案 0 :(得分:2)
我们可以使用apply
指定MARGIN = 1
来循环遍历行
nm[paste0("Rank", 1:2)] <- t(apply(nm, 1, FUN = function(x) {
i1 <- !x[1:3] #logical index giving TRUE for 0
x1 <- x[4:6][i1] #subset elements 4:6 based on i1
names(x1[order(-x1)])[1:2] #order the 'x1', extract names
}))
nm
# A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1 Rank1 Rank2
#1 0 0 1 0.06 0.84 0.89 B_TT_2.1 A_TT_1.1
#2 1 1 0 0.92 0.83 0.94 C_TT_3.1 <NA>
#3 0 1 0 0.09 0.90 0.13 C_TT_3.1 A_TT_1.1
#4 1 0 1 0.87 0.05 0.90 B_TT_2.1 <NA>
#5 0 0 0 0.13 0.11 0.14 C_TT_3.1 A_TT_1.1
注意:最好将NA
作为缺失值,而不是“NONE”,因为使用函数is.na/complete.cases/na.rm/na.omit
等删除这些值更容易。
答案 1 :(得分:1)
这是另一次尝试:
x <- df[,1:3]
y <- df[,4:6]
y[x==1] <- NA
z <- t(apply(y,1,function(x) colnames(y)[order(x, decreasing = T, na.last = T)]))[,1:2]
z[rowSums(!x)==1, 2] <- NA
df[,c("Rank1","Rank2")] <- z
# A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1 Rank1 Rank2
# 1 0 0 1 0.06 0.84 0.89 B_TT_2.1 A_TT_1.1
# 2 1 1 0 0.92 0.83 0.94 C_TT_3.1 <NA>
# 3 0 1 0 0.09 0.90 0.13 C_TT_3.1 A_TT_1.1
# 4 1 0 1 0.87 0.05 0.90 B_TT_2.1 <NA>
# 5 0 0 0 0.13 0.11 0.14 C_TT_3.1 A_TT_1.1