基于多个其他列的一列的最大值
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
)all
TRUE
:
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
我猜这个问题很具体。
我正在寻找 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
)all
TRUE
:
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