我有一个看起来像的数据帧
vessday gearval gear otherfields
152 1 OTB a
152 0 NA b
152 1 OTB c
152 1 HMD b
152 0 NA e
153 1 OTT f
153 1 OTT g
153 0 NA h
我想在我的数据帧gearkey
中添加一个字段,并为每个vessday
填充最频繁的gear
,而不计算NA(因此,当gearval==1
时)。otherfields
在那里指示数据具有其他字段的负载,并且不存在重复行。
我希望我的数据帧如下所示,除了真实的数据帧有250万条记录和几千个唯一的vessday
s。
vessday gearval gear otherfields gearkey
152 1 OTB a OTB
152 0 NA b OTB
152 1 OTB c OTB
152 1 HMD b OTB
152 0 NA e OTB
153 1 OTT f OTT
153 1 OTT g OTT
153 0 NA h OTT
我想我得到的最接近的是这个
data$gearkey[unique(data$vessday) & data$gearval==1] <- mode(data$gear)
但是我得到错误
较长的对象长度不是较短对象长度的倍数
现在,我的大脑变成了糊状的豌豆,我不知道该怎么做。。。任何帮助都将不胜感激!
更新
我可能接受@akrun的回答有点太早了:他的base R
行产生了所需的输出,但我的每个数据集(我有几个)需要2个多小时。所以,不好。
在去掉数据上的times类后,我尝试了dplyr
块,尽管它似乎产生了正确的结果,但我不能让mutate
用新列更新我的数据(仍然不知道为什么)。
因此,最终尝试了一条不同的路线,这条路线有效(每个文件不到10分钟),而且似乎不受时间类的影响:
library(data.table)
Mode <- function(x, na.rm=T) {
if(na.rm){
x = x[!is.na(x)]
}
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
df1 <- data.table(df1)
df1[, `:=`(newgear=Mode(gear), by="vessday"]
您可以尝试
library(dplyr)
Mode <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
df1 %>%
group_by(vessday) %>%
mutate(gearkey= Mode(gear))
# vessday gearval gear otherfields gearkey
#1 152 1 OTB a OTB
#2 152 0 NA b OTB
#3 152 1 OTB c OTB
#4 152 1 HMD b OTB
#5 152 0 NA e OTB
#6 153 1 OTT f OTT
#7 153 1 OTT g OTT
#8 153 0 NA h OTT
或使用base R
df1$gearkey <- with(df1, ave(gear, vessday, FUN=function(x) Mode(x)))
df1$gearkey
#[1] "OTB" "OTB" "OTB" "OTB" "OTB" "OTT" "OTT" "OTT"
更新
Catarina Aires 对Mode
的修改版本
Mode <- function(x, na.rm = T) {
if(na.rm){
x = x[!is.na(x)] }
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))] }
数据
df1 <- structure(list(vessday = c(152L, 152L, 152L, 152L, 152L, 153L,
153L, 153L), gearval = c(1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L), gear = c("OTB",
NA, "OTB", "HMD", NA, "OTT", "OTT", NA), otherfields = c("a",
"b", "c", "b", "e", "f", "g", "h")), .Names = c("vessday", "gearval",
"gear", "otherfields"), class = "data.frame", row.names = c(NA, -8L))