【问题标题】:R pivot_longer(): tidyr wide to long manipulation reverse pivot summary to individual values [duplicate]R pivot_longer():tidyr宽到长操作反向枢轴摘要到单个值[重复]
【发布时间】:2020-08-13 01:51:11
【问题描述】:

我正在尝试将代表两个城镇内每种家庭组成类型百分比的宽表操作为长表(基本上是数据透视表的反面)。

在长表中,我希望每一行代表一个家庭的家庭组成值。因此,每个组合的行数取决于提供的值,例如18 行 (town.a, singles), 8 行 (town.b, singles 等)。但是,我似乎无法根据每个 Town 列中的值来弄清楚如何进行这种扩展。

我有一个如下所示的 data.frame():

household.data <- data.frame(household.composition= c("Singles","Couples", "Families", "Single Parents", "Sharers"),
                             town.a =c(18,29,41,3,3),
                             town.b =c(8,37,48,9,3))

A 镇B 镇 列下的值代表每个镇内每个家庭组成的百分比。

我们的目标是从这种宽泛的汇总格式转换为长格式,该格式将 Household Composition 列中的值乘以 A 镇 中的数值em>Town B 列。因此,每一行将代表一个家庭的家庭组成值。例如:

再次,我知道必须有一种方法可以使用 tidyR 中的 spread/gather 或 pivot 函数来做到这一点。但是,鉴于我希望行数与百分比值相对应,我似乎无法弄清楚如何进行此扩展。

【问题讨论】:

  • 您是否希望有例如 18 行 (town.a, singles), 8 行 (town.b, singles 等?所以,每个组合的行数取决于提供的值?
  • 嗨,是的,这正是我所追求的! :)

标签: r dplyr pivot-table tidyverse tidyr


【解决方案1】:

您可以获取长格式数据并使用uncount 复制行。

library(tidyr)
pivot_longer(household.data, cols = -household.composition) %>% uncount(value)

# A tibble: 199 x 2
#   household.composition name  
#   <chr>                 <chr> 
# 1 Singles               town.a
# 2 Singles               town.a
# 3 Singles               town.a
# 4 Singles               town.a
# 5 Singles               town.a
# 6 Singles               town.a
# 7 Singles               town.a
# 8 Singles               town.a
# 9 Singles               town.a
#10 Singles               town.a
# … with 189 more rows

【讨论】:

  • 哦,多么棒的功能,我还没有遇到 uncount() 谢谢
【解决方案2】:

您可以按如下方式工作:

  1. 使用tidyr::pivot_longer将数据从宽格式转换为长格式
  2. 使用lapply根据value中的次数应用rep-licate函数
  3. 由于lapply 以列表形式提供结果,请使用dplyr::bind_rows 将它们绑定到数据帧中
  4. 删除value 列以获得所需的输出
library(dplyr)
library(tidyr)
 household.data %>% 
   pivot_longer(-household.composition, names_to = "town") %>% 
   lapply(rep, .$value) %>% 
   bind_rows() %>%
   select(-value)

【讨论】:

  • 完美运行,谢谢@HNSKD :)
  • 如果需要,您可以使用purrr::map_df 代替lapply 保存一行。
【解决方案3】:

基础 R 解决方案:

setNames(within(
  reshape(
    household.data,
    direction = "long",
    varying = grepl("town", names(household.data)),
    timevar = "town_type",
    times = NULL,
    idvar = !(grepl("town", names(household.data))),
    new.row.names = 1:(nrow(household.data) * length(grepl(
      "town", names(household.data)
    )))
  ),
  {
    rm(town)
  }
), c("household.composition", "town"))

【讨论】:

    【解决方案4】:

    data.table解决方案

    library(data.table)
    melt(setDT(household.data),id.vars = "household.composition")[rep(1:.N,value),.( household.composition,variable)]
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 2016-03-17
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多