【问题标题】:tidyr: multiple unnesting with varying NA countstidyr:具有不同 NA 计数的多个取消嵌套
【发布时间】:2016-04-23 21:05:53
【问题描述】:

我对一些整洁的行为感到困惑。我可以像这样取消嵌套单个响应:

library(tidyr)

resp1 <- c("A", "B; A", "B", NA, "B")
resp2 <- c("C; D; F", NA, "C; F", "D", "E")
resp3 <- c(NA, NA, "G; H; I", "H; I", "I")
data <- data.frame(resp1, resp2, resp3, stringsAsFactors = F)

tidy <- data %>%
  transform(resp1 = strsplit(resp1, "; ")) %>%
  unnest()

# Source: local data frame [6 x 3]
#
#      resp2   resp3 resp1
#      (chr)   (chr) (chr)
# 1 C; D; F      NA     A
# 2      NA      NA     B
# 3      NA      NA     A
# 4    C; F G; H; I     B
# 5       D    H; I    NA
# 6       E       I     B

但我需要在我的数据集中取消嵌套多个列,并且这些列具有不同数量的 NA。我试过这个,它抛出了一个错误:

data %>%
  transform(resp1 = strsplit(resp1, "; "),
            resp2 = strsplit(resp2, "; "),
            resp3 = strsplit(resp3, "; ")) %>%
  unnest()
# Error: All nested columns must have the same number of elements.

我预计上面的代码会给我与以下相同的输出:

# unnesting multiple response (desired output / is there a better way?)
data %>%
  transform(resp1 = strsplit(resp1, "; ")) %>%
  unnest() %>%
  transform(resp2 = strsplit(resp2, "; ")) %>%
  unnest() %>%
  transform(resp3 = strsplit(resp3, "; ")) %>%
  unnest()

#     resp1 resp2 resp3
#     (chr) (chr) (chr)
# 1      A     C    NA
# 2      A     D    NA
# 3      A     F    NA
# 4      B    NA    NA
# 5      A    NA    NA
# 6      B     C     G
# 7      B     C     H
# 8      B     C     I
# 9      B     F     G
# 10     B     F     H
# 11     B     F     I
# 12    NA     D     H
# 13    NA     D     I
# 14     B     E     I

我是 R 新手,但这感觉很笨拙,让我怀疑我是否在滥用我不应该滥用的东西。多次取消嵌套尝试失败是怎么回事?

【问题讨论】:

    标签: r tidyr


    【解决方案1】:

    检查this link,它显示了从您的多个列中取消嵌套的不同情况。根据文档和给出的链接,除非有一些聪明的方法可以做到这一点,否则可能只为单个列定义函数以避免歧义。

    因此,您可能必须一一取消嵌套列,下面给出的代码可能仍然很麻烦,但简化了一点。

    > resp1 <- c("A", "B; A", "B", NA, "B")
    > resp2 <- c("C; D; F", NA, "C; F", "D", "E")
    > resp3 <- c(NA, NA, "G; H; I", "H; I", "I")
    > data <- data.frame(resp1, resp2, resp3, stringsAsFactors = F)
    > data
      resp1   resp2   resp3
    1     A C; D; F    <NA>
    2  B; A    <NA>    <NA>
    3     B    C; F G; H; I
    4  <NA>       D    H; I
    5     B       E       I
    library(tidyr)
    library(dplyr)
    data %>%
    transform(resp1 = strsplit(resp1, "; "),
              resp2 = strsplit(resp2, "; "),
              resp3 = strsplit(resp3, "; ")) %>%
    unnest(resp1) %>% unnest(resp2) %>% unnest(resp3)
       resp1 resp2 resp3
    1      A     C  <NA>
    2      A     D  <NA>
    3      A     F  <NA>
    4      B  <NA>  <NA>
    5      A  <NA>  <NA>
    6      B     C     G
    7      B     C     H
    8      B     C     I
    9      B     F     G
    10     B     F     H
    11     B     F     I
    12  <NA>     D     H
    13  <NA>     D     I
    14     B     E     I
    

    【讨论】:

    • 最后一行给出 错误:错误的结果大小 (5),预期为 6 或 1。当我用unnest(resp1, resp2, resp3)替换它时也是如此。
    • 嗯,很有趣。该代码似乎对我有用。我粘贴了重现您的结果的整个代码块。
    • 我有一个类似的问题,即顺序运行 unnest 不起作用,因为它似乎在第一次调用时删除了其他嵌套列
    【解决方案2】:

    除了 Psidom 回答:默认情况下,unnest 会删除其他列表列(如果需要行重复)。

    使用.drop = FALSE 参数保留其他列。

    unnest(resp1) %&gt;% unnest(resp2) %&gt;% unnest(resp3) 行变为:

    unnest(resp1, .drop = FALSE) %>% unnest(resp2, .drop = FALSE) %>% unnest(resp3)
    

    【讨论】:

      猜你喜欢
      • 2018-01-01
      • 2019-12-31
      • 1970-01-01
      • 2023-02-06
      • 2022-01-10
      • 1970-01-01
      • 2020-03-30
      • 2015-03-06
      • 1970-01-01
      相关资源
      最近更新 更多