返回列标题作为基于条件的值

时间:2019-04-05 13:09:37

标签: r dataframe

我有一个数据框,其中包含32个变量(列),分别是UserId和一个月的31天以及350行。一个月中各天下的每个值都是从0到0的整数形式的数字。我想创建一个新的数据框,其中每个大于0的值现在都显示其对应的列名。

下面是一个示例。我想从表1到表2,但是在实现方法上还没有遇到任何问题。任何帮助都会很棒。

Table 1

UserID    01.01.2019    02.01.2019    03.01.2019    04.01.2019    05.01.2019
20        1             0             1             1             1
28        1             0             0             0             1
37        0             0             0             0             1
40        1             0             0             0             0
43        1             1             1             1             0

Table 2

UserID     Date
20         01.01.2019
20         03.01.2019
20         04.01.2019
20         05.01.2019
28         01.01.2019
28         05.01.2019
37         05.01.2019
40         01.01.2019
43         01.01.2019
43         02.01.2019
43         03.01.2019
43         04.01.2019

5 个答案:

答案 0 :(得分:1)

使用dplyr

Tab1 <- structure(list(UserID = c(20L, 28L, 37L, 40L, 43L), X01.01.2019 = c(1L, 
1L, 0L, 1L, 1L), X02.01.2019 = c(0L, 0L, 0L, 0L, 1L), X03.01.2019 = c(1L, 
0L, 0L, 0L, 1L), X04.01.2019 = c(1L, 0L, 0L, 0L, 1L), X05.01.2019 = c(1L, 
1L, 1L, 0L, 0L)), class = "data.frame", row.names = c(NA, -5L
))

library(tidyverse)
Tab2 <- Tab1 %>% 
gather(Date,var,-UserID) %>% 
filter(var==1) %>% 
select(-var) %>% 
mutate(Date=sub("X","",.$Date)) %>% 
arrange(UserID)

Tab2

   UserID       Date
1      20 01.01.2019
2      20 03.01.2019
3      20 04.01.2019
4      20 05.01.2019
5      28 01.01.2019
6      28 05.01.2019
7      37 05.01.2019
8      40 01.01.2019
9      43 01.01.2019
10     43 02.01.2019
11     43 03.01.2019
12     43 04.01.2019

答案 1 :(得分:1)

您可以简单地使用-

> library(data.table)
> setDT(melt(dt,id.vars="UserID"))[value==1,]

    UserID    variable value
 1:     20 X01.01.2019     1
 2:     28 X01.01.2019     1
 3:     40 X01.01.2019     1
 4:     43 X01.01.2019     1
 5:     43 X02.01.2019     1
 6:     20 X03.01.2019     1
 7:     43 X03.01.2019     1
 8:     20 X04.01.2019     1
 9:     43 X04.01.2019     1
10:     20 X05.01.2019     1
11:     28 X05.01.2019     1
12:     37 X05.01.2019     1

答案 2 :(得分:1)

要完成的操作是基本R选项。首先使用which查找行索引和列索引,然后从行索引获取相应的UserID,并从列索引获取列名称。

inds <- which(df == 1, arr.ind = TRUE)
data.frame(userID = df$UserID[inds[, 1]], variable = names(df)[inds[, 2]])

#   userID   variable
#1      20 01.01.2019
#2      28 01.01.2019
#3      40 01.01.2019
#4      43 01.01.2019
#5      43 02.01.2019
#6      20 03.01.2019
#7      43 03.01.2019
#8      20 04.01.2019
#9      43 04.01.2019
#10     20 05.01.2019
#11     28 05.01.2019
#12     37 05.01.2019

答案 3 :(得分:0)

如果您想使用tidyr包,则有一个名为collect的函数将执行此操作。文档为here

您的代码应类似于:

table2 <- table1 %>% 
        gather("Date", "Value", -UserID) %>%
        filter(Value >0) %>%
        select(-Value)

答案 4 :(得分:0)

这是另一个使用stack函数的基本R选项,即

subset(cbind(df[1], stack(df[-1])), values == 1)

给出,

   UserID values         ind
1      20      1 X01.01.2019
2      28      1 X01.01.2019
4      40      1 X01.01.2019
5      43      1 X01.01.2019
10     43      1 X02.01.2019
11     20      1 X03.01.2019
15     43      1 X03.01.2019
16     20      1 X04.01.2019
20     43      1 X04.01.2019
21     20      1 X05.01.2019
22     28      1 X05.01.2019
23     37      1 X05.01.2019