根据逻辑列将数值列透视得更宽

Pivot numeric value column wider based on logical columns

我有一个 table,它有一个信号值和定义信号类型的附加列。每个位置都有所有类型的信号。参见示例:

d <- data.frame("location"=c("L1","L1","L1","L2","L2","L2"),"signal"=c(1.1,1.04,1.75,1.24,2.2,22),"type1"=c(1,0,0,1,0,0),"type2"=c(0,1,0,0,1,0),"type3"=c(0,0,1,0,0,1))
d
 location signal type1 type2 type3
1       L1   1.10     1     0     0
2       L1   1.04     0     1     0
3       L1   1.75     0     0     1
4       L2   1.24     1     0     0
5       L2   2.20     0     1     0
6       L2  22.00     0     0     1

我想将此 table 调整为宽,以便每种类型的信号都有自己的列来描述信号,例如:

location type1 type2 type3
L1        1.10  1.04  1.75
L2        1.24  2.20  22.00

谢谢。

这里的技巧是将数据集转换为整齐的(长)格式,因为现在它是宽和长的混合体。这是一种方法,在最后添加 pivot_wider

library(tidyverse)
d %>%
  pivot_longer(starts_with("type")) %>%
  filter(value>0) %>%
  select(-value) %>%
  pivot_wider(names_from = name, values_from = signal)
# A tibble: 2 x 4
  location type1 type2 type3
  <chr>    <dbl> <dbl> <dbl>
1 L1        1.1   1.04  1.75
2 L2        1.24  2.2  22   

这是另一个tidyverse选项,我们可以在其中创建一个包含信号类型的新列,然后放入宽格式。本质上,对于 type 列,我们 return 具有最大值的列的列名(即 1)。

library(tidyverse)

d %>%
  mutate(name = pmap(across(starts_with("type")), ~ names(c(...)[which.max(c(...))]))) %>%
  pivot_wider(id_cols = location, names_from = name, values_from = signal)

输出

  location type1 type2 type3
  <chr>    <dbl> <dbl> <dbl>
1 L1        1.1   1.04  1.75
2 L2        1.24  2.2  22