繁体   English   中英

如何将分组的行按R中的data.table复制到列中?

[英]How to copy grouped rows into column by data.table in R?

我在这里遇到另一个问题( 如何通过R中的dplyr / tidyverse将分组的行复制到列中? )时遇到内存错误,无法使用R中的dplyr中的dplyr gather/unite/spread技术将行复制到列中

这是我正在使用的数据框作为示例:(对不起,此问题中的大多数只是复制先前的问题)

df <- data.frame(
    hid=c(1,1,1,1,2,2,2,2,2,3,3,3,3),
    mid=c(1,2,3,4,1,2,3,4,5,1,2,3,4),
    tmid=c("010","01010","010","01020",
           "010","0120","010","010","020",
           "010","01010","010","01020"),
    thid=c("010","02020","010","02020",
           "000","0120","010","010","010",
           "010","02020","010","02020")
    )

我想要的输出如下所示:

     hid   mid  tmid   thid  tmid_1  tmid_2  tmid_3  tmid_4  tmid_5  thid_1  thid_2  thid_3  thid_4  thid_5
 * <dbl> <dbl> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> <fctr> 
 1     1     1   010    010    010  01010    010  01020      0    010  02020    010  02020      0
 2     1     2 01010  02020    010  01010    010  01020      0    010  02020    010  02020      0
 3     1     3   010    010    010  01010    010  01020      0    010  02020    010  02020      0
 4     1     4 01020  02020    010  01010    010  01020      0    010  02020    010  02020      0
 5     2     1   010    000    010  0120     010    010    020    000   0120    010    010    010
 6     2     2  0120   0120    010  0120     010    010    020    000   0120    010    010    010
 7     2     3   010    010    010  0120     010    010    020    000   0120    010    010    010
 8     2     4   010    010    010  0120     010    010    020    000   0120    010    010    010
 9     2     5   020    010    010  0120     010    010    020    000   0120    010    010    010
10     3     1   010    010    010  01010    010  01020      0    010  02020    010   02020     0
11     3     2 01010  02020    010  01010    010  01020      0    010  02020    010   02020     0
12     3     3   010    010    010  01010    010  01020      0    010  02020    010   02020     0
13     3     4 01020  02020    010  01010    010  01020      0    010  02020    010   02020     0

该操作的图像如下所示: 在此处输入图片说明

我要在此操作中尝试做的是:

  • thidtmid转换为列
  • thid_xtmid_x后缀号由mid定义; 然而,最大数量的mid是不可扩展(它来自1扩散到8-10在实际大的数据集)
  • midhid分组,以定义每个hid中存储多少mid
  • 如果不存在value,则应将其填充0 (即,某些hid具有5 mid而有些只有4,因此tmid_5对于此类hid应该为0)

但是,当我在上一个问题中使用gather/unite/spread技术执行此操作时,遇到一个内存错误,提示无法分配11.4GB的内存。

可能此错误的原因是, gather函数需要先创建其参数中指定的所有组合,然后再拆分它们。 实际的数据帧大约有80,000条记录,在我的64位版本R超过16GB RAM。

您是否有任何建议,不做大量中间记录就能获得相同的结果? 也许data.table如果不需要这样的中间操作可能会有所帮助,但是我曾经使用过dplyr并且从未使用过该包。 我想让您的想法超越此问题,并根据分析的需要来学习新软件包,以采取进一步措施。

我认为您可以结合使用spreadleft_join来获得所需的内容:

library(dplyr)
library(tidyr)

a <- select(df, -thid) %>%
  spread(mid, tmid, sep="_") %>%
  rename_at(vars(matches("^mid_")), funs(paste0("t", .)))
b <- select(df, -tmid) %>%
  spread(mid, thid, sep="_") %>%
  rename_at(vars(matches("^mid_")), funs(gsub("^m", "th", .)))

left_join(df, a, by="hid") %>%
  left_join(b, by="hid")
#    hid mid  tmid  thid tmid_1 tmid_2 tmid_3 tmid_4 tmid_5 thid_1 thid_2 thid_3 thid_4 thid_5
# 1    1   1   010   010    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 2    1   2 01010 02020    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 3    1   3   010   010    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 4    1   4 01020 02020    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 5    2   1   010   000    010   0120    010    010    020    000   0120    010    010    010
# 6    2   2  0120  0120    010   0120    010    010    020    000   0120    010    010    010
# 7    2   3   010   010    010   0120    010    010    020    000   0120    010    010    010
# 8    2   4   010   010    010   0120    010    010    020    000   0120    010    010    010
# 9    2   5   020   010    010   0120    010    010    020    000   0120    010    010    010
# 10   3   1   010   010    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 11   3   2 01010 02020    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 12   3   3   010   010    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>
# 13   3   4 01020 02020    010  01010    010  01020   <NA>    010  02020    010  02020   <NA>

清理NA值应该很容易,但是可能需要您stringsAsFactors=FALSE它们(添加级别"0" ),或者仅使用stringsAsFactors=FALSE创建框架。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM