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

У меня есть большой набор данных с повторными измерениями в течение 5 периодов времени.

   2012  2009  2006  2003  2000
    3     1     4     4     1
    5     3     2     2     3
    6     7     3     5     6 

Я хочу добавить новый столбец, который представляет собой число уникальных значений в период с 2000 по 2012 годы. Например,

   2012  2009  2006  2003  2000  nunique
    3     1     4     4     1      3
    5     3     2     2     3      3
    6     7     3     5     6      4

Я работаю в R и, если это помогает, есть только 14 возможных различных значений измеренного значения в каждый период времени.

Я нашел эту страницу: подсчитать количество вхождений значения в наборе переменных в R (для каждой строки) и попробовал различные решения, предлагаемые на нем. Однако он дает мне счет каждого значения, а не количество уникальных значений. Другие подобные вопросы здесь, кажется, задают о подсчете количества уникальных значений в переменной / столбце, а не по каждой строке. Мы ценим любые предложения.

4 ответа

Решение

Хитрость заключается в использовании 'apply' и назначении каждой строки переменной (например, x). Затем вы можете написать пользовательскую функцию, в данном случае ту, которая использует "уникальный" и "длину", чтобы получить ответ, который вы хотите.

df <- data.frame('2012'=c(3,5,6), '2009'=c(1,3,7), '2006'=c(4,2,3), '2003'=c(4,2,5), '2000'=c(1,3,6))

df$nunique = apply(df, 1, function(x) {length(unique(x))})

Вот одна альтернатива

> df$nunique <- apply(df, 1, function(x) length(unique(x)))
> df
  2012 2009 2006 2003 2000 nunique
1    3    1    4    4    1       3
2    5    3    2    2    3       3
3    6    7    3    5    6       4

Если у вас большой набор данных, вы можете избежать циклического перемещения по строкам, но используйте более быстрый каркас, такой как S4Vectors:

df <- data.frame('2012'=c(3,5,6),
             '2009'=c(1,3,7),
             '2006'=c(4,2,3),
             '2003'=c(4,2,5),
             '2000'=c(1,3,6))

dup <- S4Vectors:::duplicatedIntegerPairs(as.integer(as.matrix(df)), row(df))
dim(dup) <- dim(df)
rowSums(!dup)

Или пакет matrixStats:

m <- as.matrix(df)
mode(m) <- "integer"
rowSums(matrixStats::rowTabulates(m) > 0)

Попробуйте это:

sapply(data, function(x) length(unique(x)))
Другие вопросы по тегам