基于非零填充列组合创建组

Mal*_*l_a 4 r

我很难解决这个问题.我将在示例的基础上解释它最好,让我们看看下面的数据:

    order type_a type_b type_c type_d
1     1      0     50     10      0
2     2     10      0      0     80
3     3     15      0      0     35
4     4      0      0     30      0
5     5      0     20     40      0
Run Code Online (Sandbox Code Playgroud)

并且dput:

data <- structure(list(order = c(1, 2, 3, 4, 5), type_a = c(0, 10, 15, 
0, 0), type_b = c(50, 0, 0, 0, 20), type_c = c(10, 0, 0, 30, 
40), type_d = c(0, 80, 35, 0, 0)), .Names = c("order", "type_a", 
"type_b", "type_c", "type_d"), row.names = c(NA, -5L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

我们可以看到第一列告诉我们订单号,其余列告诉我们这个订单属于什么.此外,如果type_*列填充为0,则它​​不相关.

我想创建一个新列,根据"订单描述" - > type_*列定义组.例如,对于订单1和订单5,我们具有相同的type_*列,没有填充0值,因此它们属于同一组,同样适用于订单2和3等.

我的最终结果应如下所示:

   order type_a type_b type_c type_d   group
1     1      0     50     10      0 group_1
2     2     10      0      0     80 group_2
3     3     15     10      0     35 group_2
4     4      0      0     30      0 group_3
5     5      0     20     40      0 group_1
Run Code Online (Sandbox Code Playgroud)

仅仅为了您的信息,在我的真实数据中,我确实有4列以上的类型_* - >大约有10-15个列!

感谢帮助!

Spa*_*man 8

您的组由第2列到第5列中是否存在0定义.测试0,将TRUE/FALSE值折叠为字符串,并为每个组获取唯一字符串.转换为一个因素:

> data$group = factor(apply(data[,2:5] ==0,1,paste,collapse=""))
> data
  order type_a type_b type_c type_d              group
1     1      0     50     10      0 TRUEFALSEFALSETRUE
2     2     10      0      0     80 FALSETRUETRUEFALSE
3     3     15      0      0     35 FALSETRUETRUEFALSE
4     4      0      0     30      0  TRUETRUEFALSETRUE
5     5      0     20     40      0 TRUEFALSEFALSETRUE
Run Code Online (Sandbox Code Playgroud)

现在名字很丑,所以改变级别:

> class(data$group)
[1] "factor"
> levels(data$group)=paste("group_",1:length(levels(data$group)))
> data
  order type_a type_b type_c type_d    group
1     1      0     50     10      0 group_ 2
2     2     10      0      0     80 group_ 1
3     3     15      0      0     35 group_ 1
4     4      0      0     30      0 group_ 3
5     5      0     20     40      0 group_ 2
Run Code Online (Sandbox Code Playgroud)

如果所有这些资本TRUEFALSE伤害你的眼睛,一个简单的修复将产生一个整洁的二进制数:

> data$group = factor(apply(0+(data[,2:5] ==0),1,paste,collapse=""))
> data
  order type_a type_b type_c type_d group
1     1      0     50     10      0  1001
2     2     10      0      0     80  0110
3     3     15      0      0     35  0110
4     4      0      0     30      0  1101
5     5      0     20     40      0  1001
Run Code Online (Sandbox Code Playgroud)