Как выбрать строки кадра данных в R, когда есть несколько дубликатов? - PullRequest
0 голосов
/ 17 марта 2020

Я пытаюсь взглянуть и построить график количества случаев COVID19 на каждую дату в США и Китае, используя набор данных в на этом сайте Джона Хопкинса . Я получил отличный ответ здесь о том, как получить подмножество данных для схожего графика выборки трех разных стран, благодаря Бену Болкеру:

require(RCurl)
require(foreign)
require(tidyverse) # To tip the df from long row of dates to cols (pivot_longer())
x = getURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv")

corona = (read_csv(x)
          %>% pivot_longer(cols = -c(`Province/State`, `Country/Region`, Lat, Long),
                           names_to = "date",
                           values_to = "cases")
          %>% select(`Country/Region`, date, cases)
          %>% mutate(date=as.Date(date,format="%m/%d/%y"))
          %>% drop_na(cases)
          %>% rename(country="Country/Region")
)

cc <- (corona
       %>% filter(country %in% c("Italy","Spain", "Korea, South"))
)

ccw <- (cc
        %>% pivot_wider(names_from="country",values_from="cases")
        %>% filter(cumsum(Italy>0 | Spain>0)>=5)
)

К сожалению, это намного сложнее в США и, возможно, в Китае, потому что для Соединенных Штатов существует много записей в зависимости от столбца Province/State, который в США будет соответствовать округу и штату. Отсюда и перерасчет (с одной стороны, дела в каждом штате вводятся в разные строки, и, кроме того, одни и те же числа появляются в других строках, разбитых по округам).

Мне только что удалось получить данные для США без дубликатов с использованием функции state.name, как показано ниже, но у меня нет аналогичного набора данных с именами соответствующих политических географических c разделов Китая.

Вот пример проблемы:

enter image description here

Как избежать дублирования подсчетов каждый день из-за этих перекрывающихся строк - тот факт, что они не разбились в две колонки государство и графства?

Вот рабочий код для США (Китай все еще ожидает рассмотрения):

require(RCurl)
require(foreign)
require(tidyverse) # To tip the df from long row of dates to cols (pivot_longer())



x = getURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv")

corona = (read_csv(x)
          %>% pivot_longer(cols = -c(`Province/State`, `Country/Region`, Lat, Long),
                           names_to = "date",
                           values_to = "cases")
          %>% select(`Province/State`, `Country/Region`, date, cases)
          %>% mutate(date=as.Date(date,format="%m/%d/%y"))
          %>% drop_na(cases)
          %>% rename(country="Country/Region")
          %>% rename(state="Province/State")
)

cc_with_states <- corona[is.element(corona$state,state.name),]
cc <- cc_with_states[,2:4]
us <- aggregate(cc[ ,3], FUN="sum", by=list(as.Date(cc$date)))
cc[,2:3] <- us 
cc <- cc[1:nrow(us),]

ccw <- (cc
        %>% pivot_wider(names_from="country",values_from="cases")
        %>% filter(US>1)
)

Ответы [ 2 ]

1 голос
/ 17 марта 2020

Была некоторая неопределенность относительно того, что я на самом деле спрашивал, но я получил то, что хотел:

Для случаев в Соединенных Штатах есть очень удобный state.name, позволяющий выполнять поднаборы для логической операции, которая оставляет все политические разграничения (округа), которые не являются государствами, и это привело к массовому перерасчету дел.

В случае с Китаем я должен использовать грубую силу, поскольку я не мог оштрафовать аналогичный вектор провинций , который после некоторого ознакомления с доменом кажется мне тем, что мне нужно. Получив это, я смог исключить строки с перекрывающимися счетами для городов и муниципалитетов в Китае.

Это вектор провинций и автономных администраций в Китае:

provinces <- c('Hubei', 'Guangdong', 'Henan', 'Zhejiang', 'Hunan', 'Anhui',
               'Jiangxi','Shandong','Jiangsu','Sichuan','Heilongjiang','Hebei',
               'Fujian','Guangxi','Shaanxi','Yunnan','Hainan','Guizhou','Shanxi',
               'Gansu','Hong Kong','Liaoning','Jilin','Xinjiang','Inner Mongolia',
               'Ningxia','Qinghai','Macau','Tibet')

Очевидно, проблема связана с необработанными данными в Github репозитории с использованием наклонной колонки для Province/State.

После этого он просто использовал модификацию ответа Бена Болкера на недавний связанный с этим вопрос:

require(RCurl)
require(foreign)
require(tidyverse) # To tip the df from long row of dates to cols (pivot_longer())


x = getURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv")

corona = (read_csv(x)
          %>% pivot_longer(cols = -c(`Province/State`, `Country/Region`, Lat, Long),
                           names_to = "date",
                           values_to = "cases")
          %>% select(`Province/State`, `Country/Region`, date, cases)
          %>% mutate(date=as.Date(date,format="%m/%d/%y"))
          %>% drop_na(cases)
)

united <- corona[corona$`Country/Region`=='US',]
cc_no_states <- united[!united$`Province/State`%in%state.name,]
ccn <- cc_no_states[,2:4]

cc_with_states <- corona[is.element(corona$`Province/State`,state.name),]
cc <- cc_with_states[,2:4]

mix <- rbind(ccn,cc)
mix <- aggregate(mix[,3], FUN="sum", by=list(as.Date(mix$date)))


cc[,2:3] <- mix
cc <- cc[1:nrow(mix),]

china <- corona[corona$`Country/Region`=='China',]
provinces <- c('Hubei', 'Guangdong', 'Henan', 'Zhejiang', 'Hunan', 'Anhui',
               'Jiangxi','Shandong','Jiangsu','Sichuan','Heilongjiang','Hebei',
               'Fujian','Guangxi','Shaanxi','Yunnan','Hainan','Guizhou','Shanxi',
               'Gansu','Hong Kong','Liaoning','Jilin','Xinjiang','Inner Mongolia',
               'Ningxia','Qinghai','Macau','Tibet')
china_prov <- china[is.element(china$`Province/State`,provinces),]
ccchina <- china_prov[,2:4]
temp <- aggregate(ccchina[ ,3], FUN="sum", by=list(as.Date(ccchina$date)))
ccchina[,2:3] <- temp 
ccchina <- ccchina[1:nrow(temp),]

ccw <- (cc
        %>% pivot_wider(names_from=`Country/Region`,values_from="cases")
        %>% filter(US>1)
)

ccw_china <- (ccchina
        %>% pivot_wider(names_from=`Country/Region`,values_from="cases")
        %>% filter(China>1)
)


plot(ccw_china$date, ccw_china$China, type="l", lwd=3, lty=3,
     ylab='', 
     xlab='',
     log='y',
     col=5,
     axes=FALSE,
     main = "Log-lin cumulative COVID-19 cases in US v China",
     cex.main=0.9)

at1 <- seq(min(ccw_china$date), max(ccw_china$date)+1, by=2);
axis.Date(1, at=at1, format="%b %d", las=2, cex.axis=0.7)


at2 <- 2^seq(1,30,by=1)
axis(side=2, at2, cex.axis=0.7)

abline(h=at2, lty=2, col="grey90")  # Add faint grid lines
abline(v=at1, lty=2, col="grey90")  # Add faint grid lines

lines(ccw$date, ccw$US, lwd=3, col=4)

legend(ccw_china$date[1], 70000, legend=c("China", "US"),
       col=c(5, 4), lty=c(3,1), lwd=3, cex=0.8,
       box.lty=0)


plot(ccw_china$date, ccw_china$China, type="l", lwd=3, lty=3,
     ylab='', 
     xlab='',
     xaxt="n",
     col=5,
     cex.axis=0.7,
     las=2,
     main = "COVID-19 cumulative cases in the US versus China",
     cex.main=0.9)

at1 <- seq(min(ccw_china$date), max(ccw_china$date)+1, by=2);
axis.Date(1, at=at1, format="%b %d", las=2, cex.axis=0.7)

lines(ccw$date, ccw$US, lwd=3, col=4)

legend(ccw_china$date[1], 70000, legend=c("China", "US"),
       col=c(5, 4), lty=c(3,1), lwd=3, cex=0.8,
       box.lty=0)

enter image description here

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

Похоже (из комментариев), что вы просто хотите суммировать каждый день в одну строку для каждой страны (например, все отдельные измерения штатов в США в одну строку для США). Это просто и быстро получить количество дел в день для каждой страны, используя data.table:

library(data.table)
library(RCurl)
# Read in data as a data.table
dt1 <- fread(getURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv"))

# Data.table solution: summing each column (specified with .SDcols and .SD), grouping by country/region
dt2 <- dt1[, lapply(.SD, sum), 
  .SDcols = names(dt1[, -c("Country/Region", "Province/State", "Lat", "Long")]), 
  by = "Country/Region"]

Поскольку вы теперь обновили свой собственный ответ, а не просто ответили на один из моих комментариев, показать, что вы действительно пытаетесь получить одну строку для каждой страны ... Этот график воссоздает ваш, показывая, что этот метод data.table работает при создании одной строки для каждой страны. В полном объеме:

dt2 <- melt(dt1[, lapply(.SD, sum), 
  .SDcols = names(dt1[, -c("Country/Region", "Province/State", "Lat", "Long")]), 
  by = "Country/Region"], id.vars = "Country/Region")
names(dt2)[1] <- "Country"


    # Plot it
 dt2[Country == "China", plot(log(value), typ = "l", col = "red", 
  xlab = "Days Since January 21st", xlim = c(0,70), xaxs = "i", xaxt = "n",
  ylab = "Number of Cases", ylim = c(6,12), yaxs = "i", yaxt = "n"
  )]
dt2[Country == "US", points(log(value), typ = "l", col = "blue")]
axis(1, at = seq(0, 100, 10))
axis(2, at = seq(0, 100, 2), labels = round(exp(seq(0, 100, 2)), 0))

enter image description here

...