এক কলে একটি গ্রুপের মাধ্যমে কয়েকটি ভেরিয়েবলের কয়েকটি সংক্ষিপ্তসার ফাংশন প্রয়োগ করুন


92

আমি নিম্নলিখিত তথ্য ফ্রেম আছে

x <- read.table(text = "  id1 id2 val1 val2
1   a   x    1    9
2   a   x    2    4
3   a   y    3    5
4   a   y    4    9
5   b   x    1    7
6   b   y    4    4
7   b   x    3    9
8   b   y    2    8", header = TRUE)

আমি id1 এবং id2 দ্বারা গোষ্ঠীযুক্ত ভাল 1 এবং ভাল 2 এর গড় গণনা করতে চাই এবং একই সাথে প্রতিটি id1-id2 সংমিশ্রনের জন্য সারিগুলির সংখ্যা গণনা করতে চাই। আমি প্রতিটি গণনা আলাদাভাবে সম্পাদন করতে পারি:

# calculate mean
aggregate(. ~ id1 + id2, data = x, FUN = mean)

# count rows
aggregate(. ~ id1 + id2, data = x, FUN = length)

এক কালে উভয় গণনা করার জন্য, আমি চেষ্টা করেছি

do.call("rbind", aggregate(. ~ id1 + id2, data = x, FUN = function(x) data.frame(m = mean(x), n = length(x))))

তবে, আমি একটি সতর্কতা সহ গার্ফড আউটপুট পাই:

#     m   n
# id1 1   2
# id2 1   1
#     1.5 2
#     2   2
#     3.5 2
#     3   2
#     6.5 2
#     8   2
#     7   2
#     6   2
# Warning message:
#   In rbind(id1 = c(1L, 2L, 1L, 2L), id2 = c(1L, 1L, 2L, 2L), val1 = list( :
#   number of columns of result is not a multiple of vector length (arg 1)

আমি পাতলা প্যাকেজটি ব্যবহার করতে পারতাম, তবে ডেটাসেটের আকার বাড়লে আমার ডেটা সেটটি বেশ বড় এবং পাতলা খুব ধীর (প্রায় অব্যর্থ) is

আমি aggregateএকটি কলে বিভিন্ন গণনা সম্পাদন করতে কীভাবে বা অন্যান্য ফাংশন ব্যবহার করতে পারি ?


উত্তরে aggregateউল্লিখিত রয়েছে এছাড়াও byএবং tapply
রোমান Luštrik

উত্তর:


155

আপনি এক ধাপে এটি সব করতে পারেন এবং যথাযথ লেবেলিং পেতে পারেন:

> aggregate(. ~ id1+id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x) ) )
#   id1 id2 val1.mn val1.n val2.mn val2.n
# 1   a   x     1.5    2.0     6.5    2.0
# 2   b   x     2.0    2.0     8.0    2.0
# 3   a   y     3.5    2.0     7.0    2.0
# 4   b   y     3.0    2.0     6.0    2.0

এটি দুটি আইডি কলাম এবং দুটি ম্যাট্রিক্স কলাম সহ একটি ডেটাফ্রেম তৈরি করে:

str( aggregate(. ~ id1+id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x) ) ) )
'data.frame':   4 obs. of  4 variables:
 $ id1 : Factor w/ 2 levels "a","b": 1 2 1 2
 $ id2 : Factor w/ 2 levels "x","y": 1 1 2 2
 $ val1: num [1:4, 1:2] 1.5 2 3.5 3 2 2 2 2
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr  "mn" "n"
 $ val2: num [1:4, 1:2] 6.5 8 7 6 2 2 2 2
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr  "mn" "n"

নীচে @ লর্ড.গারবেজ দ্বারা নির্দেশিত হিসাবে, এটি ব্যবহার করে "সরল" কলামগুলির সাহায্যে ডেটাফ্রেমে রূপান্তর করা যেতে পারে do.call(data.frame, ...)

str( do.call(data.frame, aggregate(. ~ id1+id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x) ) ) ) 
    )
'data.frame':   4 obs. of  6 variables:
 $ id1    : Factor w/ 2 levels "a","b": 1 2 1 2
 $ id2    : Factor w/ 2 levels "x","y": 1 1 2 2
 $ val1.mn: num  1.5 2 3.5 3
 $ val1.n : num  2 2 2 2
 $ val2.mn: num  6.5 8 7 6
 $ val2.n : num  2 2 2 2

এটি এলএইচএসে একাধিক ভেরিয়েবলের সিনট্যাক্স:

aggregate(cbind(val1, val2) ~ id1 + id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x) ) )

4
অনেক ধন্যবাদ. পার্শ্ব নোট হিসাবে, আমি কীভাবে কেবল একটি কলামে যোগ করতে পারি। যদি আমার বেশ কয়েকটি সংখ্যাসূচক কলাম থাকে তবে আমি এটি চাই না যে এটি কলামগুলির সংমিশ্রণ চাই। সমষ্টিটি শেষ হওয়ার পরে আমি অবশ্যই কলামগুলি ফেলে দিতে পারি, তবে সিপিইউ চক্রগুলি তখনই ব্যয় করা হত।
ব্রোকলি

আপনি কেবল এটির উপর দলবদ্ধ হওয়ার কারণগুলি এবং কলামগুলি একত্রিত করার জন্য দিয়েছেন। সম্ভবত ডেটাতে নেতিবাচক কলাম ইনডেক্সিং ব্যবহার করুন বা সূত্রের এলএইচএসে আপনার পছন্দসই কলামগুলি রাখুন। (সম্পাদনা দেখুন))
আইআরটিএফএম

4
আমি উইন্ডোজ 7 মেশিনে আরস্টুডিও 0.98.1014 ব্যবহার করার সময় তার আপডেটে উল্লিখিত ব্যাগটির মুখোমুখি হয়েছি। যদি আপনি কনসোলে ডেটা ফ্রেমটিকে আউটপুট হিসাবে দেখানো হয় তবে এটি স্বাভাবিক হিসাবে দেখা যায়, তবে আপনি যদি এটি ডিতে সংরক্ষণ করেন, এবং তারপরে d $ val1.mn অ্যাক্সেস করার চেষ্টা করেন, এটি NULL প্রদান করে। d দেখুন (দ) চালনা করলে ডিও ত্রুটিযুক্ত দেখা যায়। আপডেটে কোড ব্যবহার করে এটি ঠিক করা হয়েছে।
JHowIX

4
আপনার অসুবিধা হওয়ার কারণটি হ'ল "ভ্যালস" সাধারণ কলামগুলির চেয়ে দুটি কলামের সাথে ম্যাট্রিক হিসাবে ফিরে আসছে। চেষ্টা করুন d$val1[ , ""mn"]এবং এর সাথে কাঠামোটি দেখুন str
আইআরটিএফএম

4
আপনি ম্যাট্রিক্স থাকা কলামগুলিতে ডেটা ফ্রেমে ফিরে আসতে পারেন: agg <- aggregate(cbind(val1, val2) ~ id1 + id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x)))ব্যবহার করে agg_df <- do.call(data.frame, agg)এখানেও দেখুন ।
প্রভু.গারবাজ

30

এই প্রশ্নে দেওয়া:

আমি পাতলা প্যাকেজটি ব্যবহার করতে পারতাম, তবে ডেটাসেটের আকার বাড়লে আমার ডেটা সেটটি বেশ বড় এবং পাতলা খুব ধীর (প্রায় অব্যর্থ) is

তারপরে data.table( 1.9.4+) আপনি চেষ্টা করতে পারেন:

> DT
   id1 id2 val1 val2
1:   a   x    1    9
2:   a   x    2    4
3:   a   y    3    5
4:   a   y    4    9
5:   b   x    1    7
6:   b   y    4    4
7:   b   x    3    9
8:   b   y    2    8

> DT[ , .(mean(val1), mean(val2), .N), by = .(id1, id2)]   # simplest
   id1 id2  V1  V2 N
1:   a   x 1.5 6.5 2
2:   a   y 3.5 7.0 2
3:   b   x 2.0 8.0 2
4:   b   y 3.0 6.0 2

> DT[ , .(val1.m = mean(val1), val2.m = mean(val2), count = .N), by = .(id1, id2)]  # named
   id1 id2 val1.m val2.m count
1:   a   x    1.5    6.5     2
2:   a   y    3.5    7.0     2
3:   b   x    2.0    8.0     2
4:   b   y    3.0    6.0     2

> DT[ , c(lapply(.SD, mean), count = .N), by = .(id1, id2)]   # mean over all columns
   id1 id2 val1 val2 count
1:   a   x  1.5  6.5     2
2:   a   y  3.5  7.0     2
3:   b   x  2.0  8.0     2
4:   b   y  3.0  6.0     2

এই বেঞ্চমার্কটি (এবং এবং কেসগুলি) দেখতে সময়ের সাথে তুলনা করার জন্য aggregate(প্রশ্নে এবং অন্যান্য 3 টি উত্তরে ব্যবহৃত হয় )data.tableaggagg.x


12

আপনি একটি countকলাম যুক্ত করতে পারেন , এটি দিয়ে সমষ্টি করতে পারেন sum, তারপরে ফিরে পেতে স্কেল করুন mean:

x$count <- 1
agg <- aggregate(. ~ id1 + id2, data = x,FUN = sum)
agg
#   id1 id2 val1 val2 count
# 1   a   x    3   13     2
# 2   b   x    4   16     2
# 3   a   y    7   14     2
# 4   b   y    6   12     2

agg[c("val1", "val2")] <- agg[c("val1", "val2")] / agg$count
agg
#   id1 id2 val1 val2 count
# 1   a   x  1.5  6.5     2
# 2   b   x  2.0  8.0     2
# 3   a   y  3.5  7.0     2
# 4   b   y  3.0  6.0     2

এতে আপনার কলামের নামগুলি সংরক্ষণ করার এবং একটি একক countকলাম তৈরি করার সুবিধা রয়েছে ।


12

dplyrপ্যাকেজ ব্যবহার করে আপনি এটি ব্যবহার করে এটি অর্জন করতে পারেন summarise_all। এই সংক্ষিপ্তকরণ-ফাংশনটির সাহায্যে আপনি নন-গ্রুপিং কলামগুলিতে প্রতিটি অন্যান্য ফাংশন (এই ক্ষেত্রে meanএবং n()) প্রয়োগ করতে পারেন :

x %>%
  group_by(id1, id2) %>%
  summarise_all(funs(mean, n()))

যা দেয়:

     id1    id2 val1_mean val2_mean val1_n val2_n
1      a      x       1.5       6.5      2      2
2      a      y       3.5       7.0      2      2
3      b      x       2.0       8.0      2      2
4      b      y       3.0       6.0      2      2

আপনি যদি সমস্ত নন-গ্রুপিং কলামগুলিতে ফাংশন (গুলি) প্রয়োগ করতে না চান তবে আপনি যে কলামগুলিতে প্রয়োগ করতে হবে তা নির্দিষ্ট করতে পারেন বা summarise_at()ফাংশনটি ব্যবহার করে একটি বিয়োগ করে নন-ওয়ান্ট বাদ দিয়ে :

# inclusion
x %>%
  group_by(id1, id2) %>%
  summarise_at(vars(val1, val2), funs(mean, n()))

# exclusion
x %>%
  group_by(id1, id2) %>%
  summarise_at(vars(-val2), funs(mean, n()))

10

সম্ভবত আপনি মার্জ করতে চান ?

x.mean <- aggregate(. ~ id1+id2, p, mean)
x.len  <- aggregate(. ~ id1+id2, p, length)

merge(x.mean, x.len, by = c("id1", "id2"))

  id1 id2 val1.x val2.x val1.y val2.y
1   a   x    1.5    6.5      2      2
2   a   y    3.5    7.0      2      2
3   b   x    2.0    8.0      2      2
4   b   y    3.0    6.0      2      2

4

আপনি plyr::each()একাধিক ফাংশন প্রবর্তন করতে ব্যবহার করতে পারেন :

aggregate(cbind(val1, val2) ~ id1 + id2, data = x, FUN = plyr::each(avg = mean, n = length))

1

আর একটি dplyrবিকল্প হ'ল acrossযা বর্তমান দেব সংস্করণের অংশ

#devtools::install_github("tidyverse/dplyr")
library(dplyr)

x %>% 
  group_by(id1, id2) %>% 
  summarise(across(starts_with("val"), list(mean = mean, n = length)))

ফলাফল

# A tibble: 4 x 4
# Groups:   id1 [2]
  id1   id2   mean$val1 $val2 n$val1 $val2
  <fct> <fct>     <dbl> <dbl>  <int> <int>
1 a     x           1.5   6.5      2     2
2 a     y           3.5   7        2     2
3 b     x           2     8        2     2
4 b     y           3     6        2     2

packageVersion("dplyr")
[1] ‘0.8.99.9000
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.