R: сумма количества строк одних данных на основе спецификаций строк c dynamici c из других данных - PullRequest
0 голосов
/ 07 марта 2020

Рассмотрим следующие данные:

Country1 = c("Brazil", "India", "China","China","Brazil")
Date1<-as.Date(c("2001-01-21", "2002-04-13","2003-06-19","2006-06-19","2007-06-19"))
Name1<-c("B","C","A","A","A")
Data1<-data.frame(Country1,Date1,Name1)

Name2<-c("B","B","C","C","C","A","A","A")
Quality2<-c("good","good","medium","good","good","bad","good","good")
Country2<-c("China","Brazil","Taiwan","India","India","United States","China","Brazil")
Date2<-as.Date(c("2002-02-21", "1999-03-13","1998-08-19", "1996-09-13","2000-12-12","1998-07-21","2005-03-22","2003-06-19"))
Data2<-data.frame(Name2,Quality2,Country2,Date2)

В Data1 я хочу добавить столбец с именем «Результат». «Результат» (для каждой строки данных Data1) должен быть суммой количества строк данных Data2, которые удовлетворяют четырем условиям. (1) Data2 $ Name2 должен соответствовать записи строки Data1 $ Name1, (2) Data2 $ Country2 должен соответствовать записи строки данных1 $ Страна1, (3) Данные2 $ Качество2 должно быть «хорошим», (4) Данные2 $ Дата2 должно быть меньше, чем запись в строке данных1 $ Дата1. Итак, Data1 $ Result должен быть 1, 2, 0, 1 и 1.

Например, для первой строки Data1 $ Result должен быть 1, потому что Data2 имеет только 1 строку, которая удовлетворяет этим условиям: sum(Data2$Name2==as.character(Data1$Name1)[1] & Data2$Country2==as.character(Data1$Country1)[1] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[1])

Или, другими словами

sum(Data2$Name2=="B" & Data2$Country2=="Brazil" & Data2$Quality2=="good" & Data2$Date2 < "2001-01-21")

Таким же образом, для второй строки, Data1 $ Result должен быть 2, потому что Data2 имеет 2 строки, которые удовлетворяют этим условиям: sum(Data2$Name2==as.character(Data1$Name1)[2] & Data2$Country2==as.character(Data1$Country1)[2] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[2])

Или

sum(Data2$Name2=="C" & Data2$Country2=="India" & Data2$Quality2=="good" & Data2$Date2 < "2002-04-13").

Для третьей строки Data1 $ Result должен быть равен 0, поскольку в Data2 нет ни одной строки, которая удовлетворяет этим условиям: sum(Data2$Name2==as.character(Data1$Name1)[3] & Data2$Country2==as.character(Data1$Country1)[3] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[3])

В качестве альтернативы

sum(Data2$Name2=="A" & Data2$Country2=="China" & Data2$Quality2=="good" & Data2$Date2 < "2003-06-19").

То же самое касается 4-й и 5-й строк:

sum(Data2$Name2==as.character(Data1$Name1)[4] & Data2$Country2==as.character(Data1$Country1)[4] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[4])

sum(Data2$Name2==as.character(Data1$Name1)[5] & Data2$Country2==as.character(Data1$Country1)[5] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[5])

Как Начинающему в R я написал следующий код:

sum(Data2$Name2==as.character(Data1$Name1)[1:nrow(Data1)] & Data2$Country2==as.character(Data1$Country1)[1:nrow(Data1)] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[1:nrow(Data1)])

Однако он не возвращает желаемого результата. Я хочу написать динамический код c, основанный на номере строки Data1. В моих реальных данных у меня есть около 100 000 наблюдений в каждых данных.

В идеале я ищу код, который R читает в зависимости от номера строки в Data1 «n».

Например, для 1-го ряда R должен выполнить

sum(Data2$Name2==as.character(Data1$Name1)[1] & Data2$Country2==as.character(Data1$Country1)[1] & ata2$Quality2=="good" & Data2$Date2 < Data1$Date1[1])

для второго ряда

sum(Data2$Name2==as.character(Data1$Name1)[2] & Data2$Country2==as.character(Data1$Country1)[2] & ata2$Quality2=="good" & Data2$Date2 < Data1$Date1[2])

для (скажем так) 54 342-й строки

sum(Data2$Name2==as.character(Data1$Name1)[54342] & Data2$Country2==as.character(Data1$Country1)[54342] & ata2$Quality2=="good" & Data2$Date2 < Data1$Date1[54342])

для n-го ряда

sum(Data2$Name2==as.character(Data1$Name1)[n] & Data2$Country2==as.character(Data1$Country1)[n] & Data2$Quality2=="good" & Data2$Date2 < Data1$Date1[n])

Кроме того, я хочу добавить еще один столбец в Data1 с именем «Min.Date.Result», который дает мне наименьшее (самое старое) значение Data2 $ Date2, которое соответствует тем же четырем условиям. Таким образом, Data1 $ Min.Date.Result должно быть «1999-03-13», «1996-09-13», «NA», «2005-03-22», «2003-06-19».

1 Ответ

0 голосов
/ 07 марта 2020

Мы можем filter Quality2 сохранить "Good" строк, соединить их с Data1, group_by Country2 и подсчитать количество строк, где Date2 < Date1 и минимальное значение.

library(dplyr)

Data2 %>%
  filter(Quality2 == 'good') %>%
  right_join(Data1, by = c('Name2' = 'Name1', 'Country2' = 'Country1')) %>%
  group_by(Country2) %>%
  summarise(Result = sum(Date2 < Date1), 
            Date1 = min(Date2[Date2 < Date1]))

# A tibble: 3 x 3
#  Country2 Result Date1     
#  <chr>     <int> <date>    
#1 Brazil        1 1999-03-13
#2 China         0 NA        
#3 India         2 1996-09-13

Для обновленных данных мы можем изменить подход и сделать:

Data1 %>%
  left_join(Data2, by = c('Name1' = 'Name2', 'Country1' = 'Country2')) %>%
  group_by(Country1, Date1) %>%
  summarise(Result = sum(Date2 < Date1 & Quality2 == "good"), 
            Date = min(Date2[Date2 < Date1 & Quality2 == "good"]))

#  Country1 Date1      Result Date      
#  <chr>    <date>      <int> <date>    
#1 Brazil   2001-01-21      1 1999-03-13
#2 China    2003-06-19      0 NA        
#3 China    2006-06-19      1 2005-03-22
#4 India    2002-04-13      2 1996-09-13
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...