[英]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
我要在此操作中尝试做的是:
thid
和tmid
转换为列 thid_x
和tmid_x
后缀号由mid
定义; 然而,最大数量的mid
是不可扩展(它来自1扩散到8-10在实际大的数据集) mid
按hid
分组,以定义每个hid
中存储多少mid
0
(即,某些hid
具有5 mid
而有些只有4,因此tmid_5对于此类hid
应该为0) 但是,当我在上一个问题中使用gather/unite/spread
技术执行此操作时,遇到一个内存错误,提示无法分配11.4GB的内存。
可能此错误的原因是, gather
函数需要先创建其参数中指定的所有组合,然后再拆分它们。 实际的数据帧大约有80,000条记录,在我的64位版本R
超过16GB RAM。
您是否有任何建议,不做大量中间记录就能获得相同的结果? 也许data.table
如果不需要这样的中间操作可能会有所帮助,但是我曾经使用过dplyr
并且从未使用过该包。 我想让您的想法超越此问题,并根据分析的需要来学习新软件包,以采取进一步措施。
我认为您可以结合使用spread
和left_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.