কোনও ভেক্টরে x এর মান সহ উপাদানগুলির সংখ্যা গণনা


400

আমার সংখ্যার ভেক্টর রয়েছে:

numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,
         453,435,324,34,456,56,567,65,34,435)

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

উত্তর:


505

আপনি কেবল ব্যবহার করতে পারেন table():

> a <- table(numbers)
> a
numbers
  4   5  23  34  43  54  56  65  67 324 435 453 456 567 657 
  2   1   2   2   1   1   2   1   2   1   3   1   1   1   1 

তারপরে আপনি এটি সাবসেট করতে পারেন:

> a[names(a)==435]
435 
  3

অথবা আপনি যদি এর সাথে কাজ করতে আরও স্বাচ্ছন্দ্য বোধ করেন তবে এটি একটি ডেটা ফ্রেমে রূপান্তর করুন:

> as.data.frame(table(numbers))
   numbers Freq
1        4    2
2        5    1
3       23    2
4       34    2
...

21
সম্ভাব্য ভাসমান পয়েন্ট সমস্যাগুলি সম্পর্কে ভুলে যাবেন না, বিশেষত টেবিলের সাথে, যা সংখ্যার স্ট্রিংগুলিতে জোর করে।
হ্যাডলি

4
এটি একটি দুর্দান্ত বিষয়। এগুলি সমস্ত পূর্ণসংখ্যার, সুতরাং এটি এই উদাহরণে একটি বাস্তব সমস্যা নয়, তাই না?
শেন

বেপারটা এমন না. টেবিলের উপাদানগুলি শ্রেণীর পূর্ণসংখ্যার শ্রেণি (টেবিল (সংখ্যা) [1]) হয় তবে 435 একটি ভাসমান পয়েন্ট সংখ্যা। এটি পূর্ণসংখ্যা হিসাবে তৈরি করতে আপনি 435L ব্যবহার করতে পারেন।
ইয়ান ফেলো

@ ইয়ান - এই উদাহরণটিতে 435 টি কেন ভাসমান তা নিয়ে আমি বিভ্রান্ত। আপনি কি কিছুটা স্পষ্ট করে বলতে পারেন? ধন্যবাদ।
হিদার স্টার্ক

4
কেন a["435"]ইনসেটেড না a[names(a)==435]?
পোমার

262

সর্বাধিক সরাসরি উপায় sum(numbers == x)

numbers == xলজিকাল ভেক্টর তৈরি করে যা প্রতিটি জায়গাতেই সত্য হয় যেটি x হয় এবং যখন যুক্ত হয় তখন sumলজিকাল ভেক্টর সংখ্যায় জোর করা হয় যা সত্যকে 1 এবং FALSE তে 0 তে রূপান্তর করে।

তবে নোট করুন যে ভাসমান পয়েন্ট সংখ্যাগুলির জন্য এমন কিছু ব্যবহার করা ভাল sum(abs(numbers - x) < 1e-6)


1
ভাসমান পয়েন্ট ইস্যু সম্পর্কে ভাল পয়েন্ট। এটি আমার পাছাটিকে কাটায় আমি সাধারণত স্বীকার করতে চাই না।
জেডি লং

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

62

আমি সম্ভবত এটি কিছু করতে হবে

length(which(numbers==x))

তবে সত্যই, একটি আরও ভাল উপায়

table(numbers)

10
table(numbers)সহজ সমাধানের চেয়ে অনেক বেশি কাজ sum(numbers==x)করতে চলেছে, কারণ এটি তালিকার অন্যান্য সমস্ত সংখ্যার সংখ্যাও বের করে চলেছে।
কেন উইলিয়ামস

1
টেবিলের সমস্যাটি হ'ল এটি আরও জটিল ক্যালকুলাসের মধ্যে অন্তর্ভুক্ত করা আরও কঠিন, উদাহরণস্বরূপ ডেটাফ্রেমে প্রয়োগ করুন () ব্যবহার করুন
স্ক্যান

38

এছাড়াও রয়েছে count(numbers)থেকে plyrপ্যাকেজ। tableআমার মতে অনেক বেশি সুবিধাজনক ।


এর কোন ডিপ্লাইর সমতুল্য আছে?
স্টিভেক

34

আমার পছন্দসই সমাধানটি ব্যবহার করে rle, যা কোনও মান (লেবেল, xআপনার উদাহরণে) এবং একটি দৈর্ঘ্য প্রদান করবে, যা প্রতিনিধিত্ব করে যে মানটি কতবার ক্রমান্বয়ে হাজির হয়েছিল।

এর সাথে একত্রিত rleহয়ে sort, আপনার কাছে কোনও মান প্রকাশের সংখ্যা গণনা করার জন্য অত্যন্ত দ্রুত উপায় রয়েছে। এটি আরও জটিল সমস্যার সাথে সহায়ক হতে পারে।

উদাহরণ:

> numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435)
> a <- rle(sort(numbers))
> a
  Run Length Encoding
    lengths: int [1:15] 2 1 2 2 1 1 2 1 2 1 ...
    values : num [1:15] 4 5 23 34 43 54 56 65 67 324 ...

আপনি যে মানটি চান তা যদি না দেখায়, বা আপনাকে সেই মানটি পরবর্তী সময়ের জন্য সঞ্চয় করতে হয় তবে aএকটি করুন data.frame

> b <- data.frame(number=a$values, n=a$lengths)
> b
    values n
 1       4 2
 2       5 1
 3      23 2
 4      34 2
 5      43 1
 6      54 1
 7      56 2
 8      65 1
 9      67 2
 10    324 1
 11    435 3
 12    453 1
 13    456 1
 14    567 1
 15    657 1

আমি এটি বিরল বলে মনে করি যে আমি একটি মানের সমস্ত ফ্রিকোয়েন্সি জানতে চাই এবং সমস্ত মানগুলিই জানতে চাই না এবং rle মনে হয় এই সমস্তগুলি গণনা এবং সঞ্চয় করার দ্রুততম উপায়।


1
এটি, বনাম টেবিলের সুবিধা কী এটি আরও সহজেই ব্যবহারযোগ্য বিন্যাসে ফলাফল দেয়? ধন্যবাদ
হিদার স্টার্ক

@ হিদার স্টার্ক আমি বলব এর দুটি সুবিধা রয়েছে। প্রথমটি অবশ্যই টেবিল আউটপুটের চেয়ে আরও সহজেই ব্যবহৃত বিন্যাস। দ্বিতীয়টি হ'ল কখনও কখনও আমি পুরো ডেটাসেটের মধ্যে না দিয়ে "একটি সারিতে" উপাদানগুলির সংখ্যা গণনা করতে চাই। উদাহরণস্বরূপ, c(rep('A', 3), rep('G', 4), 'A', rep('G', 2), rep('C', 10))ফিরে আসবে values = c('A','G','A','G','C')এবং lengths=c(3, 4, 1, 2, 10)যা কখনও কখনও দরকারী।
জেবেকার

1
মাইক্রোবেঞ্চমার্ক ব্যবহার করে, এটি tableদ্রুত when the vector is long(আমি 100000 চেষ্টা করেছি) তবে এটি যখন ছোট হবে (সামান্য 1000 চেষ্টা করেছি) থেকে কিছুটা দীর্ঘ হবে
ক্লেমেন্টওয়াল্টার

আপনার যদি প্রচুর সংখ্যা থাকে তবে এটি সত্যিই ধীর হতে চলেছে।
স্ক্যান

19

তার জন্য আর-তে একটি স্ট্যান্ডার্ড ফাংশন রয়েছে

tabulate(numbers)


অসুবিধাটি tabulateহ'ল আপনি শূন্য এবং নেতিবাচক সংখ্যার সাথে ডিল করতে পারবেন না।
ওমার

2
তবে আপনি প্রদত্ত সংখ্যার শূন্য উদাহরণের সাথে মোকাবিলা করতে পারেন, যা অন্যান্য সমাধানগুলি পরিচালনা করে না
ডডজি

কল্পিতভাবে দ্রুত! ওমর যেমনটি বলেছেন, এটি অ-উপস্থিত মানের জন্য শূন্য গণনা দেয়, যখন আমরা একটি ফ্রিকোয়েন্সি বিতরণ তৈরি করতে চাই তখন অত্যন্ত কার্যকর useful জিরো বা নেতিবাচক পূর্ণসংখ্যার ব্যবহারের আগে ধ্রুবক যোগ করে পরিচালনা করা যায় tabulate। নোট: sortসাধারণভাবে এর সঠিক ব্যবহারের জন্য প্রয়োজনীয় মনে করা হয়: tabulate(sort(numbers))
pglpm

11
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435 453,435,324,34,456,56,567,65,34,435)

> length(grep(435, numbers))
[1] 3


> length(which(435 == numbers))
[1] 3


> require(plyr)
> df = count(numbers)
> df[df$x == 435, ] 
     x freq
11 435    3


> sum(435 == numbers)
[1] 3


> sum(grepl(435, numbers))
[1] 3


> sum(435 == numbers)
[1] 3


> tabulate(numbers)[435]
[1] 3


> table(numbers)['435']
435 
  3 


> length(subset(numbers, numbers=='435')) 
[1] 3


9

আপনি যদি পরবর্তী সময়ে উপস্থিতির সংখ্যা গণনা করতে চান তবে আপনি এই sapplyফাংশনটি ব্যবহার করতে পারেন :

index<-sapply(1:length(numbers),function(x)sum(numbers[1:x]==numbers[x]))
cbind(numbers, index)

আউটপুট:

        numbers index
 [1,]       4     1
 [2,]      23     1
 [3,]       4     2
 [4,]      23     2
 [5,]       5     1
 [6,]      43     1
 [7,]      54     1
 [8,]      56     1
 [9,]     657     1
[10,]      67     1
[11,]      67     2
[12,]     435     1
[13,]     453     1
[14,]     435     2
[15,]     324     1
[16,]      34     1
[17,]     456     1
[18,]      56     2
[19,]     567     1
[20,]      65     1
[21,]      34     2
[22,]     435     3

এটি কি কোনও উপায়ে টেবিলের চেয়ে দ্রুত?
গারিনি


3

আমি আরও একটি উপায় সুবিধাজনক বলে মনে করি তা হ'ল:

numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435)
(s<-summary (as.factor(numbers)))

এটি ডেটাসেটকে ফ্যাক্টারে রূপান্তরিত করে, এবং তারপরে সংক্ষিপ্তসার () আমাদের নিয়ন্ত্রণ योग দেয় (অনন্য মানের গণনা)।

আউটপুট হল:

4   5  23  34  43  54  56  65  67 324 435 453 456 567 657 
2   1   2   2   1   1   2   1   2   1   3   1   1   1   1 

এটি পছন্দ হলে ডেটাফ্রেম হিসাবে সংরক্ষণ করা যেতে পারে।

as.data.frame (cbind (সংখ্যা = নাম (গুলি), ফ্রেইক = গুলি), স্ট্রিংসফ্যাক্টর = এফ, সারি.নাম = 1: দৈর্ঘ্য)

এখানে row.names সারি নাম পরিবর্তন করতে ব্যবহৃত হয়েছে। সারি.নাম ব্যবহার না করে, গুলি মধ্যে কলামের নামগুলি নতুন ডাটাফ্রেমে সারি নাম হিসাবে ব্যবহৃত হয়

আউটপুট হল:

     Number Freq
1       4    2
2       5    1
3      23    2
4      34    2
5      43    1
6      54    1
7      56    2
8      65    1
9      67    2
10    324    1
11    435    3
12    453    1
13    456    1
14    567    1
15    657    1

3

টেবিল ব্যবহার করে তবে এর সাথে তুলনা না করে names:

numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435)
x <- 67
numbertable <- table(numbers)
numbertable[as.character(x)]
#67 
# 2 

tableআপনি বেশ কয়েকটি সময় বিভিন্ন উপাদান গণনা ব্যবহার করা হয় যখন দরকারী। আপনার যদি কেবল একটি গণনা প্রয়োজন, ব্যবহার করুনsum(numbers == x)


2

একটি নির্দিষ্ট উপাদান গণনা বিভিন্ন উপায় আছে

library(plyr)
numbers =c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,7,65,34,435)

print(length(which(numbers==435)))

#Sum counts number of TRUE's in a vector 
print(sum(numbers==435))
print(sum(c(TRUE, FALSE, TRUE)))

#count is present in plyr library 
#o/p of count is a DataFrame, freq is 1 of the columns of data frame
print(count(numbers[numbers==435]))
print(count(numbers[numbers==435])[['freq']])

1

লম্বা ভেক্টরগুলির তুলনায় তুলনামূলক দ্রুত এবং একটি সুবিধাজনক আউটপুট দেয় এমন একটি পদ্ধতি ব্যবহার করা হয় lengths(split(numbers, numbers))( এর শেষে এস টি নোট করুন lengths):

# Make some integer vectors of different sizes
set.seed(123)
x <- sample.int(1e3, 1e4, replace = TRUE)
xl <- sample.int(1e3, 1e6, replace = TRUE)
xxl <-sample.int(1e3, 1e7, replace = TRUE)

# Number of times each value appears in x:
a <- lengths(split(x,x))

# Number of times the value 64 appears:
a["64"]
#~ 64
#~ 15

# Occurences of the first 10 values
a[1:10]
#~ 1  2  3  4  5  6  7  8  9 10 
#~ 13 12  6 14 12  5 13 14 11 14 

আউটপুট কেবল একটি নামযুক্ত ভেক্টর।
গতিটি জেবেকারrle দ্বারা প্রস্তাবিত এবং তুলনায় বেশ লম্বা ভেক্টরগুলিতে কিছুটা দ্রুত গতিতে দেখা যায়। এখানে প্রস্তাবিত কয়েকটি কার্যক্রমে আর্ট 3.6.2 এ একটি মাইক্রোব্যাঙ্কমার্ক রয়েছে :

library(microbenchmark)

f1 <- function(vec) lengths(split(vec,vec))
f2 <- function(vec) table(vec)
f3 <- function(vec) rle(sort(vec))
f4 <- function(vec) plyr::count(vec)

microbenchmark(split = f1(x),
               table = f2(x),
               rle = f3(x),
               plyr = f4(x))
#~ Unit: microseconds
#~   expr      min        lq      mean    median        uq      max neval  cld
#~  split  402.024  423.2445  492.3400  446.7695  484.3560 2970.107   100  b  
#~  table 1234.888 1290.0150 1378.8902 1333.2445 1382.2005 3203.332   100    d
#~    rle  227.685  238.3845  264.2269  245.7935  279.5435  378.514   100 a   
#~   plyr  758.866  793.0020  866.9325  843.2290  894.5620 2346.407   100   c 

microbenchmark(split = f1(xl),
               table = f2(xl),
               rle = f3(xl),
               plyr = f4(xl))
#~ Unit: milliseconds
#~   expr       min        lq      mean    median        uq       max neval cld
#~  split  21.96075  22.42355  26.39247  23.24847  24.60674  82.88853   100 ab 
#~  table 100.30543 104.05397 111.62963 105.54308 110.28732 168.27695   100   c
#~    rle  19.07365  20.64686  23.71367  21.30467  23.22815  78.67523   100 a  
#~   plyr  24.33968  25.21049  29.71205  26.50363  27.75960  92.02273   100  b 

microbenchmark(split = f1(xxl),
               table = f2(xxl),
               rle = f3(xxl),
               plyr = f4(xxl))
#~ Unit: milliseconds
#~   expr       min        lq      mean    median        uq       max neval  cld
#~  split  296.4496  310.9702  342.6766  332.5098  374.6485  421.1348   100 a   
#~  table 1151.4551 1239.9688 1283.8998 1288.0994 1323.1833 1385.3040   100    d
#~    rle  399.9442  430.8396  464.2605  471.4376  483.2439  555.9278   100   c 
#~   plyr  350.0607  373.1603  414.3596  425.1436  437.8395  506.0169   100  b  

গুরুত্বপূর্ণভাবে, শুধুমাত্র ফাংশন যে অনুপস্থিত মান রয়েছে তা গণনা NAকরা হয় plyr::count। এগুলি ব্যবহার করে পৃথকভাবে প্রাপ্তও হতে পারেsum(is.na(vec))


1

এটি এক-মাত্রিক পারমাণবিক ভেক্টরগুলির জন্য খুব দ্রুত সমাধান। এটি নির্ভর করে match(), সুতরাং এটির সাথে সামঞ্জস্যপূর্ণ NA:

x <- c("a", NA, "a", "c", "a", "b", NA, "c")

fn <- function(x) {
  u <- unique.default(x)
  out <- list(x = u, freq = .Internal(tabulate(match(x, u), length(u))))
  class(out) <- "data.frame"
  attr(out, "row.names") <- seq_along(u)
  out
}

fn(x)

#>      x freq
#> 1    a    3
#> 2 <NA>    2
#> 3    c    2
#> 4    b    1

আপনি এটি অ্যালগরিদমটিও টুইঙ্ক করতে পারেন যাতে এটি চালিত না হয় unique()

fn2 <- function(x) {
  y <- match(x, x)
  out <- list(x = x, freq = .Internal(tabulate(y, length(x)))[y])
  class(out) <- "data.frame"
  attr(out, "row.names") <- seq_along(x)
  out
}

fn2(x)

#>      x freq
#> 1    a    3
#> 2 <NA>    2
#> 3    a    3
#> 4    c    2
#> 5    a    3
#> 6    b    1
#> 7 <NA>    2
#> 8    c    2

যে ক্ষেত্রে আউটপুটটি কাঙ্ক্ষিত, সেখানে সম্ভবত আপনার আসল ভেক্টরটিকে পুনরায় ফিরিয়ে দেওয়ার প্রয়োজন হয় না এবং দ্বিতীয় কলামটি সম্ভবত আপনার যা প্রয়োজন তা হ'ল। আপনি পাইপের সাহায্যে এক লাইনে এটি পেতে পারেন:

match(x, x) %>% `[`(tabulate(.), .)

#> [1] 3 2 3 2 3 1 2 2

1
সত্যিই দুর্দান্ত সমাধান! আমি দ্রুততম আসতে পেরেছি। ইউ <- if (is.factor (x)) x [! সদৃশ (x)] অন্য অনন্য (এক্স) ব্যবহার করে ফ্যাক্টর ইনপুটটির জন্য পারফরম্যান্সের জন্য এটি কিছুটা উন্নত হতে পারে।
তাজ

0

এটি একটি সুস্পষ্ট অর্থ সহ outerঅনুসরণের পরে সমতার একটি মেট্রিক্স পাওয়ার জন্য করা যেতে পারে rowSums
গণনা করার জন্য এবং numbersএকই ডেটাসেটে, প্রথমে একটি ডেটা.ফ্রেম তৈরি করা হয়। আপনি পৃথক ইনপুট এবং আউটপুট চাইলে এই পদক্ষেপের প্রয়োজন হবে না।

df <- data.frame(No = numbers)
df$count <- rowSums(outer(df$No, df$No, FUN = `==`))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.