数据帧的列式过滤

时间:2020-01-28 14:11:48

标签: r dataframe dplyr

我有以下df。

empid  cond1  cond2  cond3 cond4
234     1      0      1     1
7890    2      1      1     0
38476   1      1      0     1
456     0      1      1     0

空列是字符类型,其余是数字列。 我需要每个值大于0的cond1,cond2,cond3和cond4的Empids列表。 现在,我正在使用for循环从2:5创建一个列名列表。 遍历各列,选择然后过滤该特定列。

我觉得使用lapply可以更有效地完成此操作,但是我不确定如何包括要选择的列,因为我只需要在结果中添加empid列即可。

作为输出,可行的可能是一个新的列表对象,其中包含经过过滤的empid值。 因此,例如: 新的列表对象,

cond1 <- "234","7890","38476"

先谢谢您。

2 个答案:

答案 0 :(得分:2)

这是通过基数R的解决方案,

aggregate(empid ~ ind, subset(cbind(empid = df$empid, stack(df[-1])), values > 0), list)

#    ind            empid
#1 cond1 234, 7890, 38476
#2 cond2 7890, 38476, 456
#3 cond3   234, 7890, 456
#4 cond4       234, 38476

注意:

如果我们将empid保留为字符,则会使stack与factor混淆。为避免这种情况,我们可以在as.integer()中添加subset,即

aggregate(empid ~ ind, subset(cbind(empid = as.integer(df$empid), stack(df[-1])), values > 0), list)

答案 1 :(得分:1)

一个dplyr选项可能是:

df %>%
 mutate_at(vars(starts_with("cond")), ~ list(empid[. != 0]))

  empid            cond1            cond2          cond3      cond4
1   234 234, 7890, 38476 7890, 38476, 456 234, 7890, 456 234, 38476
2  7890 234, 7890, 38476 7890, 38476, 456 234, 7890, 456 234, 38476
3 38476 234, 7890, 38476 7890, 38476, 456 234, 7890, 456 234, 38476
4   456 234, 7890, 38476 7890, 38476, 456 234, 7890, 456 234, 38476

如果您要以长格式存储它,请添加tidyr

df %>%
 pivot_longer(-empid, names_to = "condition") %>%
 group_by(condition) %>%
 summarise(empid = list(empid[value != 0]))

  condition empid    
  <chr>     <list>   
1 cond1     <int [3]>
2 cond2     <int [3]>
3 cond3     <int [3]>
4 cond4     <int [2]>
相关问题