r-如何根据其他2个字段的条件子集填写字段



我有一个看起来像的数据帧

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))

最新更新