Получать подсчет групповых наблюдений с несколькими индивидуальными наблюдениями из кадра данных в R

Как получить тактику данных следующим образом:

soccer_player country position
"sam"         USA     left defender
"jon"         USA     right defender
"sam"         USA     left midfielder
"jon"         USA     offender
"bob"         England goalie
"julie"       England central midfielder
"jane"        England goalie

Чтобы выглядеть так (страна с количеством уникальных игроков в каждой стране):

country player_count
USA     2
England 3

Очевидное осложнение состоит в том, что на одного игрока есть несколько наблюдений, поэтому я не могу просто сделать table(df$country), чтобы получить количество наблюдений за страну.

Я играл с функциями table() и merge(), но не имел никакой удачи.

Ответ 1

Здесь один из способов:

as.data.frame(table(unique(d[-3])$country))
#      Var1 Freq
# 1 England    3
# 2     USA    2

Отбросьте третий столбец, удалите все повторяющиеся пары "Имя страны", затем подсчитайте вхождения каждой страны.

Ответ 2

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

List = by(df, df$country, function(x) length(unique(x$soccer_player)))
DataFrame = do.call(rbind, lapply(names(List), function(x) 
  data.frame(country=x, player_count=List[[x]])))
#  country player_count
#1 England            2
#2     USA            2

Это проще с чем-то вроде data.table:

dt = data.table(df)
dt[,list(player_count = length(unique(soccer_player))),by=country]

Ответ 3

новые функции dplyr v 3.0 обеспечивают компактное решение:

Данные:

dd <- read.csv(text='
soccer_player,country,position
"sam",USA,left defender
"jon",USA,right defender
"sam",USA,left midfielder
"jon",USA,offender
"bob",England,goalie
"julie",England,central midfielder
"jane",England,goalie')

код:

library(dplyr)

dd %>% distinct(soccer_player,country) %>% 
       count(country)

Ответ 4

Вот решение sqldf:

library(sqldf)

sqldf("select country, count(distinct soccer_player) player_count 
       from df 
       group by country")

##   country player_count
## 1 England            2
## 2     USA            2

и вот базовое решение R:

as.data.frame(xtabs(~ country, unique(df[1:2])), responseName = "player_count")

##   country player_count
## 1 England            2
## 2     USA            2

Ответ 5

Еще одна базовая опция R, используя aggregate:

> aggregate(soccer_player ~ country, dd, FUN = function(x) length(unique(x)))
#  country soccer_player
#1 England             3
#2     USA             2