【问题标题】:How to use the spread function properly in tidyr如何在 tidyr 中正确使用扩展功能
【发布时间】:2016-04-13 14:25:25
【问题描述】:

如何更改下表:

Type    Name    Answer     n
TypeA   Apple   Yes        5
TypeA   Apple   No        10
TypeA   Apple   DK         8
TypeA   Apple   NA        20
TypeA   Orange  Yes        6
TypeA   Orange  No        11
TypeA   Orange  DK         8
TypeA   Orange  NA        23

改为:

Type    Name    Yes   No   DK   NA  
TypeA   Apple   5     10   8    20
TypeA   Orange  6     11   8    23

我使用以下代码获取第一个表。

df_1 <- 
  df %>% 
  group_by(Type, Name, Answer) %>% 
  tally()  

然后我尝试使用 spread 命令到达第二张桌子,但收到以下错误消息:

“错误:所有列都必须命名”

df_2 <- spread(df_1, Answer)

【问题讨论】:

    标签: r dplyr tidyr spread


    【解决方案1】:

    我认为从df_1df_2 只需要tidyr

    library(magrittr)
    df_1 <- read.csv(text="Type,Name,Answer,n\nTypeA,Apple,Yes,5\nTypeA,Apple,No,10\nTypeA,Apple,DK,8\nTypeA,Apple,NA,20\nTypeA,Orange,Yes,6\nTypeA,Orange,No,11\nTypeA,Orange,DK,8\nTypeA,Orange,NA,23", stringsAsFactors=F)
    
    df_2 <- df_1 %>% 
      tidyr::spread(key=Answer, value=n)
    

    输出:

       Type   Name DK No Yes NA
    1 TypeA  Apple  8 10   5 20
    2 TypeA Orange  8 11   6 23
    

    【讨论】:

    • 此方法在上面显示的代码中有效。但是,当第一个表(即 df_1)上的 n 列是系统使用 tally 函数生成时。这种方法不起作用。它仍然给我错误:必须命名所有列。上面列出了我用来使用 tally 生成 n 列的代码。在这种情况下,价差似乎无法识别 n 列。还有其他建议吗?
    • 思路一:在df_1的创建结束时使用dplyr::ungroup()。
    • 想法 2:使用as.data.frame() 投射。想法3:输出dput(),这样我们可以更好地看到结构。 stackoverflow.com/questions/5963269/…。否则很难看出你是怎么得到df_1的。
    • 谢谢威比斯利。我终于弄明白了为什么我会收到“所有列必须命名”的消息。这是因为在我的实际数据集中,我有 NA 内部,当我进行传播时,它没有列的名称。我的示例数据集中没有包含 NA,所以这就是您看不到我的问题的原因。但无论如何,现在问题得到解决真是太好了。再次感谢您对此的帮助。 8-)
    【解决方案2】:

    根据 ayk 的评论,我提供了一个示例。在我看来,当您有一个 data_frame 的列具有 NA 值的因子或字符类时,如果不删除它们或重新分类数据,就无法传播。这是特定于 data_frame 的(请注意名称中带有下划线的 dplyr 类),因为当您在 data.frame 中有 NA 值时,这在我的示例中有效。例如,上面示例的略微修改版本:

    这是数据框

    library(dplyr)
    library(tidyr)
    df_1 <- data_frame(Type = c("TypeA", "TypeA", "TypeB", "TypeB"),
                       Answer = c("Yes", "No", NA, "No"),
                       n = 1:4)
    df_1
    

    这给出了一个看起来像这样的 data_frame

    Source: local data frame [4 x 3]
    
       Type Answer     n
      (chr)  (chr) (int)
    1 TypeA    Yes     1
    2 TypeA     No     2
    3 TypeB     NA     3
    4 TypeB     No     4
    

    然后,当我们尝试整理它时,我们会收到一条错误消息:

    df_1 %>% spread(key=Answer, value=n)
    Error: All columns must be named
    

    但是,如果我们删除 NA,那么它“有效”:

    df_1 %>%
        filter(!is.na(Answer)) %>%
        spread(key=Answer, value=n)
    Source: local data frame [2 x 3]
    
       Type    No   Yes
      (chr) (int) (int)
    1 TypeA     2     1
    2 TypeB     4    NA
    

    但是,删除 NA 可能不会给您想要的结果:即您可能希望将它们包含在您的整理表中。您可以直接修改数据以将 NA 更改为更具描述性的值。或者,您可以将数据更改为 data.frame,然后它就可以很好地传播:

    as.data.frame(df_1) %>% spread(key=Answer, value=n)
       Type No Yes NA
    1 TypeA  2   1 NA
    2 TypeB  4  NA  3
    

    【讨论】:

    • 这是非常好的信息。感谢您分享这些知识。 8-)
    猜你喜欢
    • 1970-01-01
    • 2020-02-05
    • 2018-02-12
    • 1970-01-01
    • 2017-03-22
    • 2014-02-09
    • 2019-12-11
    • 2021-06-02
    • 1970-01-01
    相关资源
    最近更新 更多