r - 在数据框中按组选择第一行和最后一行

标签 r dataframe aggregate

如何为以下数据框中的每个唯一 id 选择第一行和最后一行?

tmp <- structure(list(id = c(15L, 15L, 15L, 15L, 21L, 21L, 22L, 22L, 
22L, 23L, 23L, 23L, 24L, 24L, 24L, 24L), d = c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), gr = c(2L, 1L, 
1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L), mm = c(3.4, 
4.9, 4.4, 5.5, 4, 3.8, 4, 4.9, 4.6, 2.7, 4, 3, 3, 2, 4, 2), area = c(1L, 
2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 3L)), .Names = c("id", 
"d", "gr", "mm", "area"), class = "data.frame", row.names = c(NA, 
-16L))
tmp
#>    id d gr  mm area
#> 1  15 1  2 3.4    1
#> 2  15 1  1 4.9    2
#> 3  15 1  1 4.4    1
#> 4  15 1  1 5.5    2
#> 5  21 1  1 4.0    2
#> 6  21 1  2 3.8    2
#> 7  22 1  1 4.0    2
#> 8  22 1  1 4.9    2
#> 9  22 1  2 4.6    2
#> 10 23 1  1 2.7    2
#> 11 23 1  1 4.0    2
#> 12 23 1  2 3.0    2
#> 13 24 1  1 3.0    2
#> 14 24 1  1 2.0    3
#> 15 24 1  1 4.0    2
#> 16 24 1  2 2.0    3

最佳答案

快速而简短的data.table解决方案:

tmp[, .SD[c(1,.N)], by=id]

其中.SD表示(D)ata的每个(S)子集,.N是每组中的行数,tmp 是一个data.table;例如默认情况下由 fread() 提供,或者使用 setDT() 转换 data.frame 提供。

请注意,如果一个组仅包含一行,则该行将在输出中出现两次,因为该行既是该组的第一行又是最后一行。为了避免在这种情况下重复,感谢@Thell:

tmp[, .SD[unique(c(1,.N))], by=id]

或者,以下内容使 .N==1 特殊情况的逻辑变得明确:

tmp[, if (.N==1) .SD else .SD[c(1,.N)], by=id]

if 的第一部分中不需要 .SD[1],因为在这种情况下 .N1 所以 .SD 无论如何都必须只是一行。

如果您愿意,您可以将 j 包裹在 {} 中,并在 {} 中包含一整页代码。只要 {} 中的最后一个表达式返回一个类似 list 的对象即可堆叠(例如普通的 list data.tabledata.frame)。

tmp[, { ...; if (.N==1) .SD else .SD[c(1,.N)] } , by=id]

关于r - 在数据框中按组选择第一行和最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8203818/

相关文章:

r - 匹配同一数据框上另一列范围内的列中的值并返回相应的行

r - 填写网页表格,提交和下载结果

Python Pandas Dataframe 填充 NaN 值

用于将列值分组到列中的 PostgreSQL 查询

r - 计算网格中物种的出现次数

r - 为每个组 ID 创建所有可能的非 NA 值组合

python - 如何创建一个数据框,其中日期范围作为列中的值?

python - 如何比较两个单元格与 Pandas 中的字符串?

mongodb - Mongoose 聚合内部查找按字段分组

python - Pandas 聚合——如何保留所有列