按组列清单
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
我有如下数据:
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