【问题标题】:Using the spread function correctly正确使用扩展函数
【发布时间】:2019-12-15 04:17:27
【问题描述】:

我的数据“IDrel”有三个变量,“ID”、“category”和“value”,看起来是这样的:

    ID  category value
1       AU: Duflo, Esther
2   2   AF: MIT
3   3   SO: American Economic Journal: Applied Economics, 2(2), April 2010, pp.
4   4   IS: 1945-7782
5   5   AV: http://www.aeaweb.org/aej-applied/
6   6   DT: Journal Article
7   7   PY: 2010
8   8   AN: 1094392
9   9   TI: Prize Structure and Information in Tournaments: Experimental Evidence
10  10  AU: Freeman, Richard B.; Gelber, Alexander M.
11  11  AF: NBER; NBER
12  12  SO: American Economic Journal: Applied Economics, 2

“类别”有 9 个唯一值,我想将它们中的每一个都变成自己的变量,其值由“值”变量表示。理论上,这应该将变量数增加到 11 个,并将观察数减少 9/10。

所需的输出如下所示:

ID    AU:            SO.                           IS:          [more variables]

    1     Duflo, Esther   American Economic Journal    1945-7782    [more values]
    2     Freeman, Richard American Economic Journal:  [...]     

我尝试通过扩展函数来实现这一点:

IDspread<-spread(IDrel, category, value)

我确实得到了 11 个变量,但我得到了相同数量的观察值。结果对我来说似乎很荒谬,这是前 10 个观察结果:

IS:  PY:
1      <NA> <NA>
2      <NA> <NA>
3      <NA> <NA>
4 1945-7782 <NA>

我是否正确使用了这个功能?有其他选择吗?

我意识到 ID 变量不反映哪个类别/值属于哪个观察,但我需要重新排序数据以便“获取”每个观察的正确索引 ^^

【问题讨论】:

  • 请使用dput 显示示例。

标签: r tidyr


【解决方案1】:

这不是对spread() 问题的直接回答,但数据看起来非常类似于DCF 格式。

DCF 是一种以纯文本文件形式存储数据库的简单格式,可以使用基本 R 的 read.dcf() 函数直接从文件中读取。

那么,如果数据将存储在文件IDrel.dcf

AU: Duflo, Esther
AF: MIT
SO: American Economic Journal: Applied Economics, 2(2), April 2010, pp.
IS: 1945-7782
AV: http://www.aeaweb.org/aej-applied/
DT: Journal Article
PY: 2010
AN: 1094392
TI: Prize Structure and Information in Tournaments: Experimental Evidence

AU: Freeman, Richard B.; Gelber, Alexander M.
AF: NBER; NBER
SO: American Economic Journal: Applied Economics, 2

命令

read.dcf("IDrel.dcf", all = TRUE)

将返回 data.frame

                                         AU         AF                                                                  SO        IS
1                             Duflo, Esther        MIT American Economic Journal: Applied Economics, 2(2), April 2010, pp. 1945-7782
2 Freeman, Richard B.; Gelber, Alexander M. NBER; NBER                     American Economic Journal: Applied Economics, 2      <NA>
                                  AV              DT   PY      AN                                                                    TI
1 http://www.aeaweb.org/aej-applied/ Journal Article 2010 1094392 Prize Structure and Information in Tournaments: Experimental Evidence
2                               <NA>            <NA> <NA>    <NA>

请注意,空行表示新记录的开始。

R 中实现的DCF 规则在帮助文件?read.dcf 中进行了说明。

【讨论】:

    【解决方案2】:

    问题在于ID 变量的使用。它具有独特的价值。因此,如果我们在执行spread 时保留该变量,则spread 输出中的行数将等于“ID”中唯一元素的数量,而不存在的组合将是NA。删除“ID”,创建按“类别”分组的序列列(以处理重复),然后spread

    library(dplyr)
    library(tidyr)
    IDrel %>%        
       group_by(category) %>% 
       mutate(ID = row_number()) %>% # update the ID column
       spread(category, value)
    # A tibble: 2 x 10
    #    ID `AF:`    `AN:`  `AU:`                `AV:`             `DT:`     `IS:`  `PY:` `SO:`                          `TI:`                         
    #  <int> <chr>    <chr>  <chr>                <chr>             <chr>     <chr>  <chr> <chr>                          <chr>                         
    #1     1 MIT      10943… Duflo, Esther        http://www.aeawe… Journal … 1945-… 2010  American Economic Journal: Ap… Prize Structure and Informati…
    #2     2 NBER; N… <NA>   Freeman, Richard B.… <NA>              <NA>      <NA>   <NA>  American Economic Journal: Ap… <NA>   
    

    数据

    IDrel <- structure(list(ID = 1:12, category = c("AU:", "AF:", "SO:", "IS:", 
    "AV:", "DT:", "PY:", "AN:", "TI:", "AU:", "AF:", "SO:"), value = c("Duflo, Esther", 
    "MIT", "American Economic Journal: Applied Economics, 2(2), April 2010, pp.", 
    "1945-7782", "http://www.aeaweb.org/aej-applied/", "Journal Article", 
    "2010", "1094392", "Prize Structure and Information in Tournaments: Experimental Evidence", 
    "Freeman, Richard B.; Gelber, Alexander M.", "NBER; NBER", "American Economic Journal: Applied Economics, 2"
    )), class = "data.frame", row.names = c("1", "2", "3", "4", "5", 
    "6", "7", "8", "9", "10", "11", "12"))
    

    【讨论】:

    • 每个类别的行数不均匀。例如,AU: 的实例较少:(具有相应的“值),因为许多文章都是匿名编写的。您的解决方案是否会考虑到这一点(因此 AU: 的某些值留空)或者当我们分组时顺序会受到影响按类别观察?
    • @Magnus。是的,这就是我由row_number() 组的原因。假设您在不同类别中有 5、6、7 行。然后,在最后的spread 中,它将具有最大行数,即 7,以及所有不是的组合。存在将是NA
    • 您的代码似乎有效,我只是想绕开它。我只见过 group_by 动词与聚合函数一起使用(基本上就像在 SQL 查询中一样),所以我不知道它如何或为什么可以与 row_number() 函数交互。我会将其标记为答案,但请您解释一下它是如何在幕后工作的(否则请指点我一个合适的资源!)
    • @Magnus 只是为行创建一个标识符。假设您有一个元素重复了“n”次,spread 将不知道该重复元素会去哪一行,除非有一个标识符表明它是 1、2、3、... N 并且row_number() 正在这样做
    • 我知道它在做什么(我将代码通过管道传输到另一个对象并检查了索引号),我只是不确定它“如何”完成。在我看来,group_by-verb 基本上应该将每个类别的所有值聚集在一起。从这个角度来看,每个类别的行号应该相同,或者从 1 延伸到组的数值?
    猜你喜欢
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 2022-12-13
    • 2018-01-19
    • 2019-02-22
    • 1970-01-01
    • 2020-09-10
    • 2019-06-16
    相关资源
    最近更新 更多