function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
const isArray = Array.isArray;
function isPlainObject(obj) {
return isObject(obj) && (
obj.constructor === Object // obj = {}
|| obj.constructor === undefined // obj = Object.create(null)
);
}
function mergeDeep(target, ...sources){
if (!sources.length) return target;
const source = sources.shift();
if (isPlainObject(source) || isArray(source)) {
for (const key in source) {
if (isPlainObject(source[key]) || isArray(source[key])) {
if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
target[key] = {};
}else if (isArray(source[key]) && !isArray(target[key])) {
target[key] = [];
}
mergeDeep(target[key], source[key]);
} else if (source[key] !== undefined && source[key] !== '') {
target[key] = source[key];
}
}
}
return mergeDeep(target, ...sources);
}
// test...
var source = {b:333};
var source2 = {c:32, arr: [33,11]}
var n = mergeDeep({a:33}, source, source2);
source2.arr[1] = 22;
console.log(n.arr); // out: [33, 11]
Вы можете просто использовать 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
Или преобразовать его в файл data.frame, если вы больше удобно работать с этим:
> as.data.frame(table(numbers))
numbers Freq
1 4 2
2 5 1
3 23 2
4 34 2
...
Еще один способ, которым я нахожу удобным, это:
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)))
Это преобразует набор данных в коэффициент, а затем summary () дает нам контрольные итоги (подсчеты уникальных значений).
Выход:
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 (Number = names (s)), Freq = s), strAsAsFactors = F, row.names = 1: length (s))
blockquote>здесь row.names используется для переименования имен строк. без использования row.names, имена столбцов в s используются в качестве имен строк в новом фрейме данных
. Выход:
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
Если вы хотите посчитать количество появлений впоследствии, вы можете использовать функцию 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
Самый прямой способ - sum(numbers == x)
.
numbers == x
создает логический вектор, который является ИСТИННЫМ в каждом месте, где встречается x, а когда sum
ing, логический вектор принуждается к числовому, который преобразует TRUE в 1 и FALSE в 0.
Однако обратите внимание, что для чисел с плавающей запятой лучше использовать что-то вроде: sum(abs(numbers - x) < 1e-6)
.
x
в данных, а не определенное известное значение x
. Справедливости ради, в этом и был исходный вопрос. Как я уже сказал в своем ответе ниже, «я нахожу, что мне редко приходится знать частоту одного значения, а не все значения ...»
– JBecker
22 April 2013 в 21:46
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
В моем предпочтительном решении используется rle
, который вернет значение (метка, x
в вашем примере) и длину, которая представляет, сколько раз это значение появлялось в последовательности.
By комбинируя 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
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 - самый быстрый способ получить подсчитывать и хранить их все.
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)
, что иногда полезно.
– JBecker
22 April 2013 в 21:42
table
быстрее when the vector is long
(я пробовал 100000), но немного дольше, когда он короче (я пробовал 1000)
– clemlaflemme
21 June 2016 в 16:54
здесь один быстрый и грязный способ:
x <- 23
length(subset(numbers, numbers==x))
Я бы, вероятно, сделал бы что-то вроде этого
length(which(numbers==x))
Но на самом деле лучший способ -
table(numbers)
table(numbers)
собирается сделать гораздо больше работы, чем самое простое решение, sum(numbers==x)
, потому что он также будет вычислять количество всех остальных номеров в списке.
– Ken Williams
18 December 2009 в 20:41
Вы можете изменить номер на все, что пожелаете, в следующей строке
length(which(numbers == 4))
Существует также count(numbers)
из пакета plyr
. Гораздо удобнее, чем table
, на мой взгляд.
Использование таблицы, но без сравнения с 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)
Существует стандартная функция в R для этого
tabulate(numbers)
tabulate
является то, что вы не можете иметь дело с нулевым и отрицательным числом.
– omar
1 June 2016 в 15:55
a["435"]
вместоa[names(a)==435]
? – pomber 26 December 2014 в 18:08