我想通过选择a
和b
组的最后一次观察,将第一个表格转换为第二个表格,c
的第一个观察结果,对每个观察值求和d
和e
的分组以及f
的分组,检查是否存在有效日期并使用该日期。
表1:
ID a b c d e f
1 10 100 1000 10000 100000 ?
1 10 100 1001 10010 100100 5/07/1977
1 11 111 1002 10020 100200 5/07/1977
2 22 222 2000 20000 200000 6/02/1980
3 33 333 3000 30000 300000 20/12/1978
3 33 333 3001 30010 300100 ?
4 40 400 4000 40000 400000 ?
4 40 400 4001 40010 400100 ?
4 40 400 4002 40020 400200 7/06/1944
4 44 444 4003 40030 400300 ?
4 44 444 4004 40040 400400 ?
4 44 444 4005 40050 400500 ?
5 55 555 5000 50000 500000 31/05/1976
5 55 555 5001 50010 500100 31/05/1976
表2:
ID a b c d e f
1 11 111 1000 30030 300300 5/07/1977
2 22 222 2000 20000 200000 6/02/1980
3 33 333 3000 60010 600100 20/12/1978
4 44 444 4000 240150 2401500 7/06/1944
5 55 555 5000 100010 1000100 31/05/1976
我查了StackOverflow问题,我只看到了这个元素。我可以通过以下步骤进行操作。
library(data.table)
setwd('D:/Work/BRB/StackOverflow')
DT = data.table(fread('datatable.csv', header=TRUE))
AB = DT[ , .SD[.N], ID ]
AB = AB[ , c('a', 'b') ]
C = DT[ , .SD[1], ID ]
C = C[ , 'c' ]
DE = DT[ , .(d = sum(d), e = sum(e)) , by = ID ]
Final = cbind(AB, C, DE)
Final
我的问题是,我是否可以在一个转换中对变量a
,b
,c
,d
,e
执行操作,而无需拆分它变成3?
另外,我不知道如何做f
。有什么建议吗?
最后,我是R.的新手。我还可以改进其他代码吗?
答案 0 :(得分:10)
您可以改进几件事:
fread
将返回 data.table ,因此无需将其包含在data.table
中。您可以查看class(DT)
。na.strings
参数。请参阅下面的示例。总结:
DT[, .(a = a[.N],
b = b[.N],
c = c[1],
d = sum(d),
e = sum(e),
f = unique(na.omit(f)))
, by = ID]
ID a b c d e f 1: 1 11 111 1000 30030 300300 5/07/1977 2: 2 22 222 2000 20000 200000 6/02/1980 3: 3 33 333 3000 60010 600100 20/12/1978 4: 4 44 444 4000 240150 2401500 7/06/1944 5: 5 55 555 5000 100010 1000100 31/05/1976
一些解释&其他说明:
[1]
进行子集将为您提供组的第一个值。您还可以使用first
- 在 data.table 中优化的功能,从而加快速度。[.N]
进行子设置将为您提供组的最后一个值。您还可以使用last
- 在 data.table 中优化的功能,从而加快速度。c
作为变量名)。另请参阅?c
,了解c
- 函数的作用。f
- 变量,我将unique
与na.omit
结合使用。如果ID
有多个唯一日期,您也可以使用na.omit(f)[1]
。如果速度是一个问题,你可以优化上面的(thx到@Frank):
DT[order(f)
, .(a = last(a),
b = last(b),
c = first(c),
d = sum(d),
e = sum(e),
f = first(f))
, by = ID]
按f
排序会将NA
- 值设为最后。因此,现在内部GForce优化用于所有计算。
使用过的数据:
DT <- fread("ID a b c d e f
1 10 100 1000 10000 100000 ?
1 10 100 1001 10010 100100 5/07/1977
1 11 111 1002 10020 100200 5/07/1977
2 22 222 2000 20000 200000 6/02/1980
3 33 333 3000 30000 300000 20/12/1978
3 33 333 3001 30010 300100 ?
4 40 400 4000 40000 400000 ?
4 40 400 4001 40010 400100 ?
4 40 400 4002 40020 400200 7/06/1944
4 44 444 4003 40030 400300 ?
4 44 444 4004 40040 400400 ?
4 44 444 4005 40050 400500 ?
5 55 555 5000 50000 500000 31/05/1976
5 55 555 5001 50010 500100 31/05/1976", na.strings='?')
答案 1 :(得分:3)
我们可以使用tidyverse
。按照&#39; ID&#39;进行分组后,我们会根据summarise
或first
观察结果last
列
library(dplyr)
DT %>%
group_by(ID) %>%
summarise(a = last(a),
b = last(b),
c = first(c),
d = sum(d),
e = sum(e),
f = f[f!="?"][1])
# A tibble: 5 × 7
# ID a b c d e f
# <int> <int> <int> <int> <int> <int> <chr>
#1 1 11 111 1000 30030 300300 5/07/1977
#2 2 22 222 2000 20000 200000 6/02/1980
#3 3 33 333 3000 60010 600100 20/12/1978
#4 4 44 444 4000 240150 2401500 7/06/1944
#5 5 55 555 5000 100010 1000100 31/05/1976