Максимальные значения одного столбца на основе нескольких других столбцов - PullRequest
0 голосов
/ 30 апреля 2018

этот вопрос довольно специфичен, я думаю.

Я ищу R-эквивалент функции Stata egen, в частности

egen max BY varlist.

В моей таблице данных у меня есть столбец с идентификатором

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

столбец с годом наблюдения

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

год и ID не уникальны, потому что может быть больше наблюдений за один год.

Наконец-то у меня есть столбец с именами

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

Прежде всего я хочу создать пустышку, равную 1, если имя не NA, и я решил

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

Затем я хочу, чтобы R возвратил максимум фиктивного значения на основе идентификатора и года, который в Stata будет

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

На практике я хочу, чтобы R возвращал 0, если имена равны NA для всех строк с одинаковым идентификатором и годом. Таким образом, я бы получил (1,1,1,1,0,1,1,0,0), и я могу приступить к отбрасыванию строк 5,7,8. Спасибо!

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Мы можем сделать это с 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)
0 голосов
/ 30 апреля 2018

Я не знаком со 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
0 голосов
/ 30 апреля 2018

Вот попытка использования ave, но эта логика будет работать с любой функцией группировки, которую вы можете знать. Ищите NA s по группам, посмотрите, не являются ли они (! / 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)
...