Dplyr এর সাথে সম্পর্কিত ফ্রিকোয়েন্সি / অনুপাত


153

মনে করুন আমি প্রতিটি গ্রুপের মধ্যে বিভিন্ন মানের অনুপাত গণনা করতে চাই। উদাহরণস্বরূপ, mtcarsডেটা ব্যবহার করে আমি কীভাবে এক সাথে am (স্বয়ংক্রিয় / ম্যানুয়াল) দ্বারা গিয়ার সংখ্যার তুলনামূলক ফ্রিকোয়েন্সি গণনা করব ?dplyr

library(dplyr)
data(mtcars)
mtcars <- tbl_df(mtcars)

# count frequency
mtcars %>%
  group_by(am, gear) %>%
  summarise(n = n())

# am gear  n
#  0    3 15 
#  0    4  4 
#  1    4  8  
#  1    5  5 

আমি যা অর্জন করতে চাই:

am gear  n rel.freq
 0    3 15      0.7894737
 0    4  4      0.2105263
 1    4  8      0.6153846
 1    5  5      0.3846154

1
এই শতাংশগুলি কি আপনি চান আসল সংখ্যাগুলি? বীজগণিতভাবে তারা কোথা থেকে আসছে? আহ, %৯% হ'ল ১৫ / (১৫ + ৪), 21% হ'ল 4 / (15 + 4) এবং তারপরে আমি == 1 62% 8 / (8 + 5) ইত্যাদি পেয়েছি।
স্পেসডম্যান

1
@ স্পিডম্যান হ্যাঁ, আমি যে নম্বরটি চাই তা চাই এবং ফ্রাঙ্ক সঠিক, এ্যাম ভেরিয়েবল (
+৯

2
এটি সত্যই মনে হয় prop.table()/ এর স্থানীয় নেভিগেশন dplyr বাস্তবায়ন খুঁজছেন sweep()। এছাড়াও, অন্যান্য প্রশ্নের মধ্যে কিছু লোক ভেরিয়েবল বা ভেরিয়েবল-ইন্টারঅ্যাকশনগুলির জন্য শূন্য-গণনা অন্তর্ভুক্ত করার বিকল্প জিজ্ঞাসা করছে
স্মিচ

উত্তর:


285

এটা চেষ্টা কর:

mtcars %>%
  group_by(am, gear) %>%
  summarise(n = n()) %>%
  mutate(freq = n / sum(n))

#   am gear  n      freq
# 1  0    3 15 0.7894737
# 2  0    4  4 0.2105263
# 3  1    4  8 0.6153846
# 4  1    5  5 0.3846154

ডিপিপ্লায়ার ভিগনেট থেকে :

আপনি যখন একাধিক ভেরিয়েবল দ্বারা গোষ্ঠী করেন, প্রতিটি সংক্ষিপ্তকরণটি গ্রুপিংয়ের এক স্তর থেকে ছাড়ে। এটি প্রগতিশীলভাবে একটি ডেটাসেট রোল আপ করতে সহজ করে তোলে।

সুতরাং, এর পরে , 'গিয়ার'-এ summariseনির্দিষ্ট করা শেষ গ্রুপিং ভেরিয়েবলটি group_byখোসা ছাড়ানো হবে। ইন mutateধাপ, ডাটা অবশিষ্ট গোষ্ঠীবদ্ধ ভেরিয়েবলের (গুলি) দ্বারা 'টা' দলবদ্ধ করা হয়, এখানে। আপনি প্রতিটি পদক্ষেপে গ্রুপিং চেক করতে পারেন groups

পিলিংয়ের ফলাফল অবশ্যই group_byকলটিতে গ্রুপিং ভেরিয়েবলের ক্রমের উপর নির্ভরশীল । group_by(am)আপনার কোডটি আরও স্পষ্ট করে তুলতে আপনি পরবর্তী কাজ করতে ইচ্ছুক হতে পারেন ।

রাউন্ডিং এবং প্রিটিফিকেশন এর জন্য দয়া করে @ টাইলার রিঙ্কার দ্বারা সুন্দর উত্তরটি দেখুন।


5
আমি কেবল এটি সমাধানটি আবিষ্কার করেছি, তবে কেন জানি না কেন গ্রুপের sum(n)উপর কাজ করে amএবং gear
গ্রুপও

7
ভিগনেটটি দেখুন : "আপনি যখন একাধিক ভেরিয়েবল দ্বারা গোষ্ঠী করেন, তখন প্রতিটি সংক্ষিপ্তকরণ গ্রুপিংয়ের একটি স্তর থেকে ছাঁটা হয়।"
হেনরিক

7
ভাল - আপনি যদি summariseএটির পরে থামেন তবে এটি বলবে কোন গ্রুপগুলি বাকি আছে। ওহ dplyr শিলা ...
স্পেসডম্যান

সহজ এবং পরিষ্কার। থিওরি বন্ধ করার আগে আমি কখনই জানতাম না, ধন্যবাদ!
শিক্সিয়াং ওয়াং

সুন্দর। সহজ এবং কার্যকর। দারূন কাজ!
ব্যবহারকারী 2550228

38

আপনি count()ফাংশনটি ব্যবহার করতে পারেন , যা এর সংস্করণ অনুসারে আলাদা আচরণ করেছে dplyr:

  • dplyr 0.7.1: একটি গোষ্ঠীভুক্ত টেবিলটি ফিরিয়ে দেয় : আপনাকে আবার গোষ্ঠীবদ্ধ করতে হবেam

  • dplyr <0.7.1: একটি দলবদ্ধ টেবিল ফেরত দেয় , সুতরাং আপনাকে আবার গ্রুপ করার দরকার নেই, যদিও আপনি ungroup()পরবর্তী কৌশলগুলির জন্য চাইবেন

dplyr 0.7.1

mtcars %>%
  count(am, gear) %>%
  group_by(am) %>%
  mutate(freq = n / sum(n))

dplyr <0.7.1

mtcars %>%
  count(am, gear) %>%
  mutate(freq = n / sum(n))

একটি মধ্যে এই ফলাফল দলবদ্ধ টেবিল , আপনি আরও বিশ্লেষণের জন্য এটি ব্যবহার করতে চান, এটা দরকারী মুছে ফেলার জন্য হতে পারে দলবদ্ধ সঙ্গে অ্যাট্রিবিউট ungroup()


1
এটি dplyr0.7.1 এ একটি অবৈধ উত্তর বলে মনে হচ্ছে । এটি "am" এর প্রতিটি স্তরের পরিবর্তে সামগ্রিকভাবে "গিয়ার" এ ফ্রিকোয়েন্সি গণনা করে।
এডউইন

30

@ হেনরিক এর ব্যবহারের পক্ষে আরও ভাল কারণ এটি কলামের অক্ষর তৈরি করবে এবং এটি আর সংখ্যাসূচক নয় তবে আপনি যা চেয়েছিলেন তার সাথে মেলে ...

mtcars %>%
  group_by (am, gear) %>%
  summarise (n=n()) %>%
  mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%"))

##   am gear  n rel.freq
## 1  0    3 15      79%
## 2  0    4  4      21%
## 3  1    4  8      62%
## 4  1    5  5      38%

সম্পাদনা করুন কারণ স্পেসডম্যান এর জন্য জিজ্ঞাসা করেছিল :-)

as.rel_freq <- function(x, rel_freq_col = "rel.freq", ...) {
    class(x) <- c("rel_freq", class(x))
    attributes(x)[["rel_freq_col"]] <- rel_freq_col
    x
}

print.rel_freq <- function(x, ...) {
    freq_col <- attributes(x)[["rel_freq_col"]]
    x[[freq_col]] <- paste0(round(100 * x[[freq_col]], 0), "%")   
    class(x) <- class(x)[!class(x)%in% "rel_freq"]
    print(x)
}

mtcars %>%
  group_by (am, gear) %>%
  summarise (n=n()) %>%
  mutate(rel.freq = n/sum(n)) %>%
  as.rel_freq()

## Source: local data frame [4 x 4]
## Groups: am
## 
##   am gear  n rel.freq
## 1  0    3 15      79%
## 2  0    4  4      21%
## 3  1    4  8      62%
## 4  1    5  5      38%

6
আপনি সর্বদা একটি formatপদ্ধতির সাথে একটি এস 3 "শতাংশ" শ্রেণি তৈরি করতে পারেন যা শতকরা চিহ্ন যোগ করে ... # ওভারকিল
স্পেসডম্যান 4:44

: এই পারে বাস্তবায়নকারী খুব আকর্ষণীয় হতে stackoverflow.com/questions/13483430/...
Spacedman

যদি কেউ এই উদাহরণে গড়, এসডি এবং এসই গণনা করে তবে কী হবে?
user3655531

6

dplyr0.7.1. তে হেনরিকের সমাধানটি কার্যকর করার জন্য এখানে একটি সাধারণ ক্রিয়াকলাপ ।

freq_table <- function(x, 
                       group_var, 
                       prop_var) {
  group_var <- enquo(group_var)
  prop_var  <- enquo(prop_var)
  x %>% 
    group_by(!!group_var, !!prop_var) %>% 
    summarise(n = n()) %>% 
    mutate(freq = n /sum(n)) %>% 
    ungroup
}

Error in bind_rows_(x, .id) : Column am` সংখ্যাসূচক থেকে চরিত্রে রূপান্তরিত হতে পারে না
f0nzie

5

আমি এই পুনরাবৃত্তি কাজের জন্য একটি ছোট ফাংশন লিখেছি:

count_pct <- function(df) {
  return(
    df %>%
      tally %>% 
      mutate(n_pct = 100*n/sum(n))
  )
}

আমি তখন এটির মতো ব্যবহার করতে পারি:

mtcars %>% 
  group_by(cyl) %>% 
  count_pct

এটি ফিরে আসে:

# A tibble: 3 x 3
    cyl     n n_pct
  <dbl> <int> <dbl>
1     4    11  34.4
2     6     7  21.9
3     8    14  43.8

3

অনেক উত্তর থাকা সত্ত্বেও, আরও একটি পদ্ধতির prop.tableসাথে মিলিত হয় যা এর সাথে dplyrবা ব্যবহার করে data.table

library("dplyr")
mtcars %>%
    group_by(am, gear) %>%
    summarise(n = n()) %>%
    mutate(freq = prop.table(n))

library("data.table")
cars_dt <- as.data.table(mtcars)
cars_dt[, .(n = .N), keyby = .(am, gear)][, freq := prop.table(n) , by = "am"]

1
এতদূর সহজ পন্থা
পার্সেলটাংয়ে

1

এই উত্তরটি মতিফুর উত্তরের উপর ভিত্তি করে।

প্রথমে আমি এটিকে সংশোধন করেছিলাম যাতে আমি স্কিপেন বিকল্পটি ব্যবহার করে ফ্রিক্স কলামটি বৈজ্ঞানিক স্বরলিপি কলাম হিসাবে ফিরে পাব না।

তারপরে আমি দশমিকের চেয়ে এক শতাংশ পাওয়ার জন্য উত্তরটি 100 এর সাথে একাধিক করি, শতাংশ হিসাবে ফ্রিক কলামটি পড়া সহজ করে তোলে।

getOption("scipen") 
options("scipen"=10) 
mtcars %>%
count(am, gear) %>% 
mutate(freq = (n / sum(n)) * 100)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.