我正在处理看起来像这样的原始数据集:
df <- data.frame("ID" = c("Alpha", "Alpha", "Alpha", "Alpha",
"Beta","Beta", "Beta","Beta" ),
"Year" = c(1970, 1970, 1980, 1990, 1970, 1980,
1980,1990),
"Val" = c(1,0,1,1,0,0,0,1),
"Val2" = c(0,0,0,1,0,1,0,1),
"Val3" = c(0,2.34,1.3,0,0,2.34,3.2,1.3))
数据有点脏,因为我对每个ID和Year标识符有多个观察结果-例如我在1970年的Alpha中有2个不同的行。在1980年的Beta中也是如此。
问题在于,感兴趣的变量Val
Val2
Val3
在重复的行中(以id / year计)具有不同的分数。
我想找到一种简洁的方法来产生以下最终数据帧:
final<- data.frame("ID" = c("Alpha", "Alpha", "Alpha",
"Beta", "Beta","Beta" ),
"Year" = c( 1970, 1980, 1990, 1970,
1980,1990),
"Val" = c(1,1,1,0,0,1),
"Val2" = c(0,0,1,0,1,1),
"Val3" = c(2.34,1,0,0,3.2,1.3))
final
逻辑如下:
1)我希望每个ID /年只有一个obs
2)对于每个感兴趣的变量(Val
Val2
Val3
),我只想保留单个ID /年输出中具有较高值的观测值
进行说明。在df
中,对Alpha / 1970有重复的观察。我想将其减少到一行。 Val
取值为0和1,在final
数据帧中仅保留1。 Val2
的取值为0和0,因此我只是在final
中保留0。 Val2
的值为2.34和1,因此我想保留在final
数据框中。
我想我可以使用data.table命令同时在这一栏做
library(dplyr)
val1<- df %>% select(ID:Val)
library(data.table)
setDT(val1)[order(-Val)][,.SD[1,], by = .(ID, Year)]
val2<- df %>% select(ID,Year,Val2)
library(data.table)
setDT(val2)[order(-Val2)][,.SD[1,], by = .(ID, Year)]
,然后将这些值合并在一起,但是我必须为其运行该操作的几列,而我一直在寻找一种更简洁的方法。
我希望它足够清楚
非常感谢您的提前帮助
答案 0 :(得分:1)
这是一个选择
library(dplyr)
df %>%
group_by(ID, Year) %>%
summarise_all(max)
# for specific set of columns, use `summarise_at`
# summarise_at(vars(starts_with("Val")), max)
或带有data.table
library(data.table)
nm1 <- grep('^Val\\d*$", names(df))
setDT(df)[, (nm1) := lapply(.SD, max), .(ID, Year), .SDcols = nm1]
答案 1 :(得分:1)
您可以这样做:
aggregate(. ~ ID + Year, FUN = max, data = df)
ID Year Val Val2 Val3
1 Alpha 1970 1 0 2.34
2 Beta 1970 0 0 0.00
3 Alpha 1980 1 0 1.30
4 Beta 1980 0 1 3.20
5 Alpha 1990 1 1 0.00
6 Beta 1990 1 1 1.30