按组列清单

Making lists by group

我有如下数据:

library(data.table)
dat <- structure(list(year2006 = c("1110", "1110", "1110", "1110", "1120", 
"1120", "1120", "1120"), group2006 = c("1", "2", "3", "4", "1", 
"2", "3", "4"), min2006 = c("1.35", "2", "3.7", 
"4.25", "5.6", "4.45", "3.09", "1.13"), 
    year2007 = c("1110", "1110", "1110", "1110", "1120", "1120", 
    "1120", "1120"), group2007 = c("1", "2", "3", "4", "1", 
    "2", "3", "4"), min2007 = c("5", "5.05", "5", 
    "1.59", "2.3", "3", "4.05", "5.16"
    )), row.names = c(NA, -8L), class = c("data.table", "data.frame"
))
dat

   year2006  group2006 min2006 year2007  group2007 min2007
1:     1110          1    1.35     1110          1       5
2:     1110          2       2     1110          2    5.05
3:     1110          3     3.7     1110          3       5
4:     1110          4    4.25     1110          4    1.59
5:     1120          1     5.6     1120          1     2.3
6:     1120          2    4.45     1120          2       3
7:     1120          3    3.09     1120          3    4.05
8:     1120          4    1.13     1120          4    5.16

我想做的是在 min200x 中为每个类别创建一个数字列表 year200x

期望的输出:

   cat       year2006                         year2007
1:     1110  c("1.35", "2", "3.7", "4.25")    c("5", "5.05", "5", "1.59") 
2:     1120  c("5.6", "4.45", "3.09", "1.13") c("2.3", "3", "4.05", "5.16")

我想我可以做类似的事情:

setDT(dat)[, cat := list(min2006), by=year2006]

但这不起作用(它只是将 min2006 项放入新列 cat 中)。而且即使有,也只能提供2006年的解决方案。我该怎么办?

我不确定为什么测试数据中的列都是字符,而所需输出中的列是数字。此外,您要求按组列出数字列表,但您的预期输出显示一个向量。

不过,这里有一个创建列表列的 tidyverse 解决方案。

library(tidyverse)

x <- dat %>% 
  mutate(across(everything(), as.numeric)) %>% 
  group_by(year2006) %>% 
  select(year2006, starts_with("min")) %>% 
  summarise(across(everything(), lst))
x
# A tibble: 2 × 3
  year2006 min2006      min2007     
     <dbl> <named list> <named list>
1     1110 <dbl [4]>    <dbl [4]>   
2     1120 <dbl [4]>    <dbl [4]>

并且,例如,

x$min2006
$min2006
[1] 1.35 2.00 3.70 4.25

$min2006
[1] 5.60 4.45 3.09 1.13

如果您的输入实际上是数字,您可能会丢失 mutate

编辑

... 要获得分组列的正确名称,您可以将 %>% rename(cat=year2006) 添加到管道中。为遗漏道歉。

类似的方法

data.table


library(data.table)
COLS <- grep(names(df), pattern = "^min", value = TRUE)

setDT(df)[, lapply(.SD, list), .SDcol = COLS, by = year2006]
#>    year2006            min2006         min2007
#> 1:     1110    1.35,2,3.7,4.25   5,5.05,5,1.59
#> 2:     1120 5.6,4.45,3.09,1.13 2.3,3,4.05,5.16

reprex package (v2.0.1)

创建于 2022-05-31

这里还有一个基本的R解决方案,

l1 <- lapply(split.default(dat, gsub('\D+', '', names(dat))), function(i) 
                                       aggregate(as.matrix(i[3]) ~ as.matrix(i[1]), i, list))

do.call(cbind, l1)[-3]

#  year2006          2006.min2006       2007.min2007
#1     1110    1.35, 2, 3.7, 4.25   5, 5.05, 5, 1.59
#2     1120 5.6, 4.45, 3.09, 1.13 2.3, 3, 4.05, 5.16