我得到的数据是宽格式的。每一行都涉及当前表格外部的一个变量以及与该变量相关的可能值。我正在尝试:(1)将其转换为长格式,(2)嵌套已转换的值。
示例
library(tibble)
df_1 <-
tribble(~key, ~values.male, ~values.female, ~values.red, ~values.green, ~value,
"gender", 0.5, 0.5, NA, NA, NA,
"age", NA, NA, NA, NA, "50",
"color", NA, NA, TRUE, FALSE, NA,
"time_of_day", NA, NA, NA, NA, "noon")
## # A tibble: 4 x 6
## key values.male values.female values.red values.green value
## <chr> <dbl> <dbl> <lgl> <lgl> <chr>
## 1 gender 0.5 0.5 NA NA NA
## 2 age NA NA NA NA 50
## 3 color NA NA TRUE FALSE NA
## 4 time_of_day NA NA NA NA noon
在这个例子中,我们可以看到
gender
可以是 female = 0.5
或者 male = 0.5
。但是,age
只能有一个值 50
。从第三行可以得知,color
可以有值 red = TRUE
或者 green = FALSE
,并且 time_of_day = noon
。因此,数据透视表应该采用嵌套的形式:
my_pivoted_df <-
structure(
list(
var_name = c("gender", "age", "color", "time_of_day"),
vals = list(
structure(
list(
level = c("male", "female"),
value = c(0.5,
0.5)
),
row.names = c(NA, -2L),
class = c("tbl_df", "tbl", "data.frame")
),
"50",
structure(
list(
level = c("red", "green"),
value = c(TRUE,
FALSE)
),
row.names = c(NA, -2L),
class = c("tbl_df", "tbl", "data.frame")
),
"noon"
)
),
row.names = c(NA, -4L),
class = c("tbl_df", "tbl",
"data.frame")
)
## # A tibble: 4 x 2
## var_name vals
## <chr> <list>
## 1 gender <tibble [2 x 2]>
## 2 age <chr [1]>
## 3 color <tibble [2 x 2]>
## 4 time_of_day <chr [1]>
我的尝试解决方案
df_1
存在几个问题。首先,当前列名的命名不太方便。例如value
等标题并不理想,因为它们与pivot_longer()
的".value"
机制相冲突。其次,当key
有多个选项(例如color
的“red”和“green”)时,df_1
具有values
(复数),但是当key
只有一个选项时(例如age
),则为value
(单数)。
以下是我受此答案启发而编写的未成功代码。
library(tidyr)
library(dplyr)
df_1 %>%
rename_with( ~ paste(.x, "single", sep = "."), .cols = value) %>% ## changed the header because otherwise it breaks
pivot_longer(cols = starts_with("val"),
names_to = c("whatevs", ".value"), names_sep = "\\.")
## # A tibble: 8 x 7
## key whatevs male female red green single
## <chr> <chr> <dbl> <dbl> <lgl> <lgl> <chr>
## 1 gender values 0.5 0.5 NA NA NA
## 2 gender value NA NA NA NA NA
## 3 age values NA NA NA NA NA
## 4 age value NA NA NA NA 50
## 5 color values NA NA TRUE FALSE NA
## 6 color value NA NA NA NA NA
## 7 time_of_day values NA NA NA NA NA
## 8 time_of_day value NA NA NA NA noon
我缺少一些处理技巧来解决这个问题。
df_pivoted
),使其data
列不存在?相反,data
下的值将在value
列中。我想也许使用dplyr::coalesce()
作为最后一步可能会起到作用,但我还是有些犹豫。如果我只有单个值,例如df_2 <- tribble(~key, ~value, "age", "50", "income", "100000", "time_of_day", "noon")
,这可能会出问题。 - Emmandf_2
中,那么会发生什么?在我的真实数据中,这种情况经常发生。然后输出将在列名方面有所不同(key
和data
),而不是df_1
场景中的(在展开的输出格式中为key
、level
、value
、data
)。如何确保输出始终只有key
和value
列,并在需要时添加level
列? - Emmandf_pivoted %>% unnest(data) %>% {if(all(c("data", "value") %in% colnames(.))) (mutate(., value = coalesce(data, value)) %>% select(-data)) else .} %>% nest()
。但我认为这不太易读,也可能不是最佳编码实践。如果有更简单/更清晰的解决方案,我会很高兴。谢谢! - Emman