gpt4 book ai didi

R tidyverse 如何在彼此之后做两个 pivot_longer 而不是一个

转载 作者:行者123 更新时间:2023-12-04 08:59:52 25 4
gpt4 key购买 nike

假设有以下数据:

structure(list(uuid = c("abc", "def", "hij"), Q1r1 = c(0L, 1L, 
1L), Q1r2 = c(1L, 1L, 1L), Q1r3 = c(1L, 0L, 1L), Q2r1c1 = c(4L,
3L, 5L), Q2r1c2 = 2:4, Q2r1c3 = c(1L, 5L, 2L), Q2r2c1 = c(3L,
3L, 4L), Q2r2c2 = c(2L, 5L, 4L), Q2r2c3 = c(1L, 4L, 5L), Q3r1 = c(5L,
9L, 7L), Q3r2 = c(10L, 3L, 8L), Q3r3 = c(6L, 8L, 5L)), class = "data.frame", row.names = c(NA,
-3L))
这使:
  uuid Q1r1 Q1r2 Q1r3 Q2r1c1 Q2r1c2 Q2r1c3 Q2r2c1 Q2r2c2 Q2r2c3 Q3r1 Q3r2 Q3r3
1 abc 0 1 1 4 2 1 3 2 1 5 10 6
2 def 1 1 0 3 3 5 3 5 4 9 3 8
3 hij 1 1 1 5 4 2 4 4 5 7 8 5
现在假设我想对所有 Q1 和 Q3 列的数据进行 pivot_longer(其中这些列中的 r1、r2 和 r3 表示要创建的行)。
这相对简单:
dat %>%
 pivot_longer(cols      = c(starts_with("Q1"), starts_with("Q3")),
              names_sep = "r",
              names_to  = c('.value', 'brand’))
这使:
# A tibble: 9 x 10
uuid Q2r1c1 Q2r1c2 Q2r1c3 Q2r2c1 Q2r2c2 Q2r2c3 brand Q1 Q3
<chr> <int> <int> <int> <int> <int> <int> <chr> <int> <int>
1 abc 4 2 1 3 2 1 1 0 5
2 abc 4 2 1 3 2 1 2 1 10
3 abc 4 2 1 3 2 1 3 1 6
4 def 3 3 5 3 5 4 1 1 9
5 def 3 3 5 3 5 4 2 1 3
6 def 3 3 5 3 5 4 3 0 8
7 hij 5 4 2 4 4 5 1 1 7
8 hij 5 4 2 4 4 5 2 1 8
9 hij 5 4 2 4 4 5 3 1 5
现在,这是我的问题:是否还有一种方法可以将两个枢轴彼此分开,即首先是 pivot_longer Q1,然后是 pivot_longer Q3?
我问的原因是,或者我也想旋转 Q2 和 Q3(但在 Q2 中,行标识符是 c1​​、c2、c3,我希望在 pivoting_longer 之后有两个结果列 Q2r1 和 Q2r2,而行标识符是 r1 , r2, r3 用于 Q3,因此上面带有 names_sepnames_to 的简单代码不再起作用)。一位同事告诉我,在其他软件中,您可以连接单个 pivot_longers,所以我想知道在 R 中是否也可以这样做。
注意:我知道如何在一轮中为 Q2 和 Q3 进行旋转。我真的只是想知道是否可以拆分旋转并一个接一个地进行。
我以 Q1 和 Q3 为中心的第一个示例的预期输出是:
# A tibble: 9 x 10
uuid Q2r1c1 Q2r1c2 Q2r1c3 Q2r2c1 Q2r2c2 Q2r2c3 brand Q1 Q3
<chr> <int> <int> <int> <int> <int> <int> <chr> <int> <int>
1 abc 4 2 1 3 2 1 1 0 5
2 abc 4 2 1 3 2 1 2 1 10
3 abc 4 2 1 3 2 1 3 1 6
4 def 3 3 5 3 5 4 1 1 9
5 def 3 3 5 3 5 4 2 1 3
6 def 3 3 5 3 5 4 3 0 8
7 hij 5 4 2 4 4 5 1 1 7
8 hij 5 4 2 4 4 5 2 1 8
9 hij 5 4 2 4 4 5 3 1 5
我想以 Q2 和 Q3 为中心的第二个示例的所需输出是:
# A tibble: 9 x 8
uuid Q1r1 Q1r2 Q1r3 brand Q2r1 Q2r2 Q3
<chr> <int> <int> <int> <chr> <int> <int> <int>
1 abc 0 1 1 brand1 4 3 5
2 abc 0 1 1 brand2 2 2 10
3 abc 0 1 1 brand3 1 1 6
4 def 1 1 0 brand1 3 3 9
5 def 1 1 0 brand2 3 5 3
6 def 1 1 0 brand3 5 4 8
7 hij 1 1 1 brand1 5 4 7
8 hij 1 1 1 brand2 4 4 8
9 hij 1 1 1 brand3 2 5 5

最佳答案

好吧,在更好地理解了这个问题之后,我能想到的唯一答案是骇人听闻的。你在评论中提到了一个;这是另一个。这围绕使用灵活的正则表达式来选择列。然后它通过 Reduce() 将数据帧连接在一起(或者,如果您愿意,可以将 if 换成 purrr::reduce())。另外,请注意,这是执行从宽到长的多个独立时间(和组合),而不是按顺序执行。

col_starts <- c("Q2", "Q3")

lapply(col_starts, function(x) {

df %>%
pivot_longer(matches(paste0("^", x)),
names_pattern = "(Q\\d.*)[rc](\\d)$",
names_to = c(".value", "brand")) %>%
select(uuid, brand:ncol(.), everything(), -matches(paste0("^", setdiff(col_starts, x), collapse = "|")))

}) %>% Reduce(function(x, y) left_join(x, y, by = intersect(names(x), names(y))), .)
# A tibble: 9 x 8
uuid brand Q2r1 Q2r2 Q1r1 Q1r2 Q1r3 Q3
<chr> <chr> <int> <int> <int> <int> <int> <int>
1 abc 1 4 3 0 1 1 5
2 abc 2 2 2 0 1 1 10
3 abc 3 1 1 0 1 1 6
4 def 1 3 3 1 1 0 9
5 def 2 3 5 1 1 0 3
6 def 3 5 4 1 1 0 8
7 hij 1 5 4 1 1 1 7
8 hij 2 4 4 1 1 1 8
9 hij 3 2 5 1 1 1 5
这是一个仅保留 uuid 的版本, brand和派生列(imo 更容易阅读)
lapply(c("Q2", "Q3"), function(x) {

df %>%
pivot_longer(matches(paste0("^", x)),
names_pattern = "(Q\\d.*)[rc](\\d)$",
names_to = c(".value", "brand")) %>%
select(uuid, brand, starts_with(x))

}) %>% Reduce(function(x, y) left_join(x, y, by = c("uuid", "brand")), .)

关于R tidyverse 如何在彼此之后做两个 pivot_longer 而不是一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63613081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com