【问题标题】:Avoid NA in column after pivot_wider()在 pivot_wider() 之后的列中避免 NA
【发布时间】:2020-10-09 10:22:57
【问题描述】:

是否有可能在pivot_wider() 之后“上移”观察结果并删除列中观察结果上方的NA's?我尝试lag() 列,但这似乎很麻烦。显然,我不受此方法的约束,但更愿意留在tidyverse

library(tidyverse)

set.seed(1111)

df <- data.frame(
  item = as.numeric(sample(1:20)),
  clust = as.numeric(sample(1:3, 20, replace = TRUE))
)

df %>%
  arrange(clust, item) %>%
  rowid_to_column() %>%
  pivot_wider(names_from = clust, values_from = item, names_prefix = "Cluster_") %>%
  select(-rowid)

当前输出如下所示:

# A tibble: 20 x 3
   Cluster_1 Cluster_2 Cluster_3
       <dbl>     <dbl>     <dbl>
 1         3        NA        NA
 2        13        NA        NA
 3        14        NA        NA
 4        15        NA        NA
 5        16        NA        NA
 6        17        NA        NA
 7        19        NA        NA
 8        20        NA        NA
 9        NA         1        NA
10        NA         4        NA
11        NA         6        NA
12        NA         7        NA
13        NA         8        NA
14        NA         9        NA
15        NA        12        NA
16        NA        18        NA
17        NA        NA         2
18        NA        NA         5
19        NA        NA        10
20        NA        NA        11

所需的输出如下所示:

   Cluster_1 Cluster_2 Cluster_3
       <dbl>     <dbl>     <dbl>
 1         3         1         2
 2        13         4         5
 3        14         6        10
 4        15         7        11
 5        16         8        NA
 6        17         9        NA
 7        19        12        NA
 8        20        18        NA

我知道,这种方法会危害数据集,但这仅仅是出于美观的原因,因为 tibble 随后会导出到 LATEX 文档中,并且仅有助于集群分组的可视化。

【问题讨论】:

  • 您的真实数据中有多少个集群?是只有 3 个还是您无法手动处理的更大数字?
  • 集群的数量取决于底层数据集。它源自Ckmeans.1d.dp(),因此无法控制。我想要一个通用的解决方案,它按集群编号将项目列分组。

标签: r tidyr


【解决方案1】:

你可以像这样实现你想要的输出:

library(tidyverse)

set.seed(1111)

df <- data.frame(
  item = as.numeric(sample(1:20)),
  clust = as.numeric(sample(1:3, 20, replace = TRUE))
)

df %>%
  arrange(clust, item) %>%
  group_by(clust) %>% 
  mutate(id =row_number()) %>%
  pivot_wider(names_from = clust, values_from = item, names_prefix = "Cluster_") %>%
  select(-id)
#> # A tibble: 8 x 3
#>   Cluster_1 Cluster_2 Cluster_3
#>       <dbl>     <dbl>     <dbl>
#> 1         3         1         2
#> 2        13         4         5
#> 3        14         6        10
#> 4        15         7        11
#> 5        16         8        NA
#> 6        17         9        NA
#> 7        19        12        NA
#> 8        20        18        NA

【讨论】:

  • 感谢您的解决方案。我也在旋转之前尝试了group_by(),但似乎rowid_to_column() 的使用是一个错误。该函数将 rowID 按顺序添加到新列,而与之前的 group_by() 无关。 row_number() 确实尊重之前的分组。
  • (: 是的。我也尝试过使用 rowid_to_column()。但是 rowid_... 只是添加了 df 的行名,而 row_number 使每个组的 row_numbers。最佳 S。
【解决方案2】:

这里是使用split 并调整长度的方法。

s <- split(df$item, df$clust)
as.data.frame(lapply(s, function(x) `length<-`(sort(x), max(lengths(s)))))
#   X1 X2 X3
# 1  3  1  2
# 2 13  4  5
# 3 14  6 10
# 4 15  7 11
# 5 16  8 NA
# 6 17  9 NA
# 7 19 12 NA
# 8 20 18 NA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2012-12-15
    相关资源
    最近更新 更多