dplyr使用两个键将数据转换为宽格式

时间:2018-08-20 13:47:38

标签: r dataframe dplyr reshape

我有一个看起来像这样的数据框:

ID, Type, Unit, Value, Status
A, L1, cm, 100, F
A, L2, %, 70, F
A, L3, cm, 100, F
A, L4, %, 80, F
B, L1, cm, 100, T
B, L2, %, 70, T
B, L3, cm, 100, T
B, L4, %, 80, T

我想将其转换为宽格式:

ID, L1(cm), L2(%), L3(cm), L4(%), Status
A, 100, 70, 100, 80, F
B, 100, 70, 100, 80, T

我正在dplyr中使用散布函数,键是Type,值是Value。我想我将不得不在ID列上再次进行此操作。我想知道是否有标准的方法可以做到,或者是否有更简洁的方法。

2 个答案:

答案 0 :(得分:4)

我们可以使用tidyverse。用pasteunite(不太灵活)创建一个具有“类型”和“单位”的串联列,然后在删除不需要的列之后将spread设置为“宽”格式

library(tidyverse)
df1 %>%
  mutate(TypeUnit = paste0(Type, "(", Unit, ")")) %>%
  select(-Type, -Unit) %>%
  spread(TypeUnit, Value) 
#   ID Status  L1(cm)  L2(%)  L3(cm)  L4(%)
#1  A      F     100     70     100     80
#2  B      T     100     70     100     80

数据

df1 <- structure(list(ID = c("A", "A", "A", "A", "B", "B", "B", "B"), 
Type = c(" L1", " L2", " L3", " L4", " L1", " L2", " L3", 
" L4"), Unit = c("cm", "%", "cm", "%", "cm", "%", "cm", "%"
), Value = c(100L, 70L, 100L, 80L, 100L, 70L, 100L, 80L), 
Status = c(" F", " F", " F", " F", " T", " T", " T", " T"
)), row.names = c(NA, -8L), class = "data.frame")

答案 1 :(得分:1)

@akrun的答案肯定很漂亮。 如果您还想尝试reshape,则下面的方法也可以使用,但之后可能需要重命名列名。

使用相同的数据

df <- data.frame(ID = c("A", "A", "A", "A", "B", "B", "B", "B"), 
             Type = c(" L1", " L2", " L3", " L4", " L1", " L2", " L3", " L4"), 
             Unit = c("cm", "%", "cm", "%", "cm", "%", "cm", "%"), 
             Value = c(100, 70, 100, 80, 100, 70, 100, 80), 
             Status = c(" F", " F", " F", " F", " T", " T", " T", " T"))

使用软件包reshape2

library(reshape2)
dcast(df, ID + Status  ~ Type + Unit, value.var = "Value" )

输出

  ID Status  L1_cm  L2_%  L3_cm  L4_%
1  A      F    100    70    100    80
2  B      T    100    70    100    80