【问题标题】:Pivot data with values from different columns in R使用 R 中不同列的值透视数据
【发布时间】:2020-09-27 13:52:15
【问题描述】:

抱歉,如果我重复发布,但我尝试了我在 stackoverflow 中看到的不同方法,但无法完全解决问题或理解我为什么会遇到它。

所以我有一个这样的数据集:

council_name <- c("Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barking and Dagenham","Barnet","Barnet")
period <- c("1st 2006", "1st 2006", "1st 2006", "1st 2006", "2nd 2006", "2nd 2006", "2nd 2006", "2nd 2006", "1st 2006", "1st 2006") 
category <- c ("glass", "fridges", "paper", "glass", "glass", "fridges", "paper", "glass", "glass", "fridges")
data <- c(333, 222, 100, 98, 450, 540, 33, 450, 560, 120)
category2 <- c ("collected", "collected", "collected", "no donors", "collected", "collected", "collected", "no donors", "collected", "collected")
df <- data.frame (council_name, period, category, category2, data)

而我想要的是这样的:

council_name <- c("Barking and Dagenham","Barking and Dagenham","Barnet")
period <- c("1st 2006", "2nd 2006", "1st 2006") 
glass <- c(333, 450, 560)
fridges <- c(222,540,120)
paper <- c(100, 33, NA)
no.donors <- c(98, 450, NA)
df.desired <- data.frame (council_name, period, glass, fridges, paper, no.donors)

我一直在尝试使用数据透视函数做多种事情,但事实上我需要从 category1 和 category2 中提取列名,但用 df 中同一列的值填充单元格,这给了我各种各样的问题。

非常感谢您的帮助!

【问题讨论】:

    标签: r dplyr data.table pivot tidyr


    【解决方案1】:

    以下方法是data.table的一种:

    使用您的数据:

    library(data.table)
    
    setDT(df)
    
    df[, sum(data), by = .(council_name, period, category, category2)][, dcast(.SD, council_name + period ~ category + category2, value.var = "V1")]
    

    会产生什么

    df
               council_name   period fridges_collected glass_collected glass_no donors paper_collected
    1: Barking and Dagenham 1st 2006               222             333              98             100
    2: Barking and Dagenham 2nd 2006               540             450             450              33
    3:               Barnet 1st 2006               120             560              NA              NA
    

    这基本上是您的数据,除了名称和列顺序的差异。这些可以通过 data.table 的 setnamessetcolorder 来修复。

    里面有什么:

    • sum(data), by = .(council_name... 将为理事会、时期、类别和类别2 的每个独特组合汇总您的数据。请考虑只运行这一位来查看输出:df[, sum(data), by = .(council_name, period, category, category2)]
    • 第二部分,[, dcast(.SD, council_name + period ~ category + category2, value.var = V1)] 将之前生成的长表转换为宽表(您想要的格式)。它的意思是它希望行中的理事会名称和句点以及列中的类别和类别2,并且值变量是V1(V1是第一个链式命令中给出的虚拟名称,因为我刚刚写了sum(data),没有给出它是一个名字)。

    希望对你有帮助。

    【讨论】:

    • 谢谢!只是一个简单的问题:在第二部分中,我收到以下错误“valnames %chin% varnames 中的错误:x 类型为 'double'(必须是 'character' 或 NULL)”,这是指哪个变量?抱歉,不太习惯用data.table
    • 您可以使用fun.aggregate = sumdcast 步骤中完成所有操作:dcast(df, council_name + period ~ category + category2, value.var = 'data', fun.aggregate = sum)(实际上在这个特定示例中,您甚至不需要fun.aggregate = sum,但总的来说我认为添加该参数将使输出与您的答案中的代码相同)
    • @AntVal 我错过了最后一部分关于 V1 的一些引用。请看我的编辑
    【解决方案2】:

    在这种情况下,您可以使用spread() 函数。代码如下:

    spread(data=df, key=category, value=data)
    

    【讨论】:

    • 有 2 个类别因此不起作用。不过谢谢
    【解决方案3】:

    这是一个tidyverse 解决方案,使用pivot_wider 将数据转换为宽格式,然后使用rename 更改列名。

    library(tidyverse)
    
    df %>%
      # Pivot from long to wide format using the first two columns as id cols and using both category and category2 columns to get the new column names
      pivot_wider(id_cols = c(council_name,period),
                  names_from = c(category, category2),
                  values_from = data) %>%
      # Rename the columns
      rename("glass" = "glass_collected",
             "fridges" = "fridges_collected",
             "paper" = "paper_collected",
             "no.donors" = "glass_no donors")
    
    # A tibble: 3 x 6
    # council_name         period   glass fridges paper no.donors
    # <fct>                <fct>    <dbl>   <dbl> <dbl>     <dbl>
    # 1 Barking and Dagenham 1st 2006   333     222   100        98
    # 2 Barking and Dagenham 2nd 2006   450     540    33       450
    # 3 Barnet               1st 2006   560     120    NA        NA
    

    【讨论】:

    • 感谢@Jonathan V. Solórzano。它并没有完全得到我想要的,因为多个单元格有多个数据值,这没有多大意义,因为在原始数据集中,每个“数据”单元格在组合 id_cols 时都有一个唯一值。我收到此错误:Data 中的值不是唯一标识的;输出将包含列表列。 * 使用values_fn = list(Data = list) 抑制此警告。 * 使用values_fn = list(Data = length) 确定重复出现的位置 * 使用values_fn = list(Data = summary_fun) 汇总重复
    • 您可以将values_fn = list(data = length) 作为参数添加到pivot_wider 以识别重复出现的位置并检查它们是否有意义。使用此选项,重复条目的值应为 2。如果您想保留重复的条目,可以将values_fn = list(data = list) 添加到pivot_wider,然后添加unnest 列。
    【解决方案4】:

    这是另一个在 dcast 内聚合的 data.table 方法:

    library(data.table)
    setDT(df)
    
    dcast(df, council_name + period ~ category + category2, value.var = "data", fun.aggregate = sum)
    #            council_name   period fridges_collected glass_collected glass_no donors paper_collected
    # 1: Barking and Dagenham 1st 2006               222             333              98             100
    # 2: Barking and Dagenham 2nd 2006               540             450             450              33
    # 3:               Barnet 1st 2006               120             560               0               0
    

    【讨论】:

      猜你喜欢
      • 2019-01-22
      • 1970-01-01
      • 2021-10-13
      • 2013-06-15
      • 1970-01-01
      • 2020-05-05
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多