基于多个其他列的一列的最大值

Maximum values of one column based on multiple other columns

我猜这个问题很具体。

我正在寻找 Stata egen 函数的 R 等价物,特别是

egen max BY varlist.

在我的数据中 table 我有一个 ID 为

的列
ID <- c(1,1,2,2,3,4,5,6,6)

包含观察年份的列

year <- c(2000,2000,2001,2002,2002,2003,2004,2004,2004)

year和ID不是唯一的,因为一年可以有更多的观察

最后我有一个名称列

names <- c("Mark",NA,"John","John",NA,"Sarah","Julia",NA,NA).

首先,如果名称不是 NA,我想生成一个等于 1 的虚拟对象,我想

dummy <-  ifelse(!is.na(names),1,0)

然后我希望 R return 基于 ID 和年份的虚拟变量的最大值,这在 Stata 中是

egen MAX = max(dummy), by(ID year)

实际上,如果具有相同 ID 和年份的所有行的名称为 NA,我希望 R 为 return 0。所以我会得到 (1,1,1,1,0,1,1,0,0) 并且我可以继续删除第 5、7、8 行。 谢谢!

这是使用 ave 的尝试,但此逻辑适用于您可能知道的任何分组函数。按组查找NA,看是不是(!/Negate)allTRUE:

ave(is.na(dat[["names"]]), dat[c("ID","year")], FUN=Negate(all))
#[1]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE

其中 dat 是:

dat <- data.frame(ID,year,names, stringsAsFactors=FALSE)

我们可以用 tidyverse

library(dplyr)
df1 %>%
   group_by(ID, year) %>% 
   mutate(dummy = as.integer(any(!is.na(names))))
# A tibble: 9 x 4
# Groups: ID, year [7]
#     ID  year names  dummy
#  <dbl> <dbl> <fctr> <int>
#1  1.00  2000 Mark       1
#2  1.00  2000 <NA>       1
#3  2.00  2001 John       1
#4  2.00  2002 John       1
#5  3.00  2002 <NA>       0
#6  4.00  2003 Sarah      1
#7  5.00  2004 Julia      1
#8  6.00  2004 <NA>       0
#9  6.00  2004 <NA>       0

数据

df1 <- data.frame(ID, year, names)

我不熟悉 Stata,但根据您的描述,这应该可以解决问题:

mydata <- data.frame(
  ID = c(1,1,2,2,3,4,5,6,6),
  year = c(2000,2000,2001,2002,2002,2003,2004,2004,2004),
  names = c("Mark",NA,"John","John",NA,"Sarah","Julia",NA,NA),
  stringsAsFactors = FALSE
)

mydata$dummy <- as.integer(!is.na(mydata$names))

max_dummy <- aggregate(mydata$dummy, mydata[c("ID","year")], max)

has_name <- subset(merge(mydata, max_dummy), x > 0)[-5]

has_name