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

Допустим, у меня есть фрейм данных с 10 числовыми переменными V1-V10 (столбцы) и несколькими строками (регистры).

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

Например, число вхождений числового значения 99 в этой отдельной строке для V2, V3, V6, которое, очевидно, имеет минимум 0 (ни один из трех не имеет значения 99) и максимум 3 (все три имеют значение 99).

Я действительно ищу эквивалент функции SPSSCOUNT: "COUNT создает числовую переменную, которая для каждого случая подсчитывает вхождения одного и того же значения (или списка значений) в списке переменных".

Я думал о table() и библиотека plyr count(), но я не могу понять это. Векторизованные вычисления предпочтительнее. Большое спасибо!

6 ответов

Решение

Пытаться

apply(df,MARGIN=1,table)

куда df твой data.frame, Это вернет список с одинаковой длиной количества строк в вашем data.frame. Каждый элемент списка соответствует строке data.frame (в том же порядке), и это таблица, в которой содержимое - это число вхождений, а имена - соответствующие значения.

Например:

df=data.frame(V1=c(10,20,10,20),V2=c(20,30,20,30),V3=c(20,10,20,10))
#create a data.frame containing some data
df #show the data.frame
  V1 V2 V3
1 10 20 20
2 20 30 10
3 10 20 20
4 20 30 10
apply(df,MARGIN=1,table) #apply the function table on each row (MARGIN=1)
[[1]]

10 20 
 1  2 

[[2]]

10 20 30 
 1  1  1 

[[3]]

10 20 
 1  2 

[[4]]

10 20 30 
 1  1  1 

#desired result

Если вам нужно посчитать любое конкретное слово / букву в строке.

#Let df be a data frame with four variables (V1-V4)
             df <- data.frame(V1=c(1,1,2,1,L),V2=c(1,L,2,2,L),
             V3=c(1,2,2,1,L), V4=c(L, L, 1,2, L))

Для подсчета количества L в каждом ряду просто используйте

#This is how to compute a new variable counting occurences of "L" in V1-V4.      
df$count.L <- apply(df, 1, function(x) length(which(x=="L")))

Результат будет выглядеть так

> df
  V1 V2 V3 V4 count.L
1  1  1  1 L       1
2  1  L  2 L       2
3  2  2  2  1      0
4  1  2  1  2      0

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

#Some example data
df <- data.frame(a=c(1,1,2,2,3,9),b=c(1,2,3,2,3,1))
df
#  a b
#1 1 1
#2 1 2
#3 2 3
#4 2 2
#5 3 3
#6 9 1

levels=unique(do.call(c,df)) #all unique values in df
out <- sapply(levels,function(x)rowSums(df==x)) #count occurrences of x in each row
colnames(out) <- levels
out
#     1 2 3 9
#[1,] 2 0 0 0
#[2,] 1 1 0 0
#[3,] 0 1 1 0
#[4,] 0 2 0 0
#[5,] 0 0 2 0
#[6,] 1 0 0 1

Вот еще одно простое решение, наиболее близкое к тому, что делает команда COUNT в SPSS, - создание новой переменной, которая для каждого случая (т. Е. Строки) подсчитывает вхождения данного значения или списка значений в списке переменных.

#Let df be a data frame with four variables (V1-V4)
df <- data.frame(V1=c(1,1,2,1,NA),V2=c(1,NA,2,2,NA),
       V3=c(1,2,2,1,NA), V4=c(NA, NA, 1,2, NA))

 #This is how to compute a new variable counting occurences of value "1" in V1-V4.      
    df$count.1 <- apply(df, 1, function(x) length(which(x==1)))

Обновленный фрейм данных содержит новую переменную count.1 точно так же, как и команда SPSS COUNT.

 > df
      V1 V2 V3 V4 count.1
    1  1  1  1 NA       3
    2  1 NA  2 NA       1
    3  2  2  2  1       1
    4  1  2  1  2       2
    5 NA NA NA NA       0

Вы можете сделать то же самое, чтобы посчитать, сколько раз значение "2" встречается в строке в V1-V4. Обратите внимание, что вам нужно выбрать столбцы (переменные) в df, к которым применяется функция.

df$count.2 <- apply(df[1:4], 1, function(x) length(which(x==2)))

Вы также можете применить аналогичную логику для подсчета количества пропущенных значений в V1-V4.

df$count.na <- apply(df[1:4], 1, function(x) sum(is.na(x)))

Конечный результат должен быть именно тем, что вы хотели:

 > df
      V1 V2 V3 V4 count.1 count.2 count.na
    1  1  1  1 NA       3       0        1
    2  1 NA  2 NA       1       1        2
    3  2  2  2  1       1       3        0
    4  1  2  1  2       2       2        0
    5 NA NA NA NA       0       0        4

Это решение может быть легко обобщено до диапазона значений. Предположим, мы хотим подсчитать, сколько раз значение 1 или 2 встречается в V1-V4 на строку:

df$count.1or2 <- apply(df[1:4], 1, function(x) sum(x %in% c(1,2)))

Решение с функциями из пакета dplyr будет следующим:

Используя пример набора данных из ответа LechAttacks:

      df <- data.frame(V1=c(1,1,2,1,NA),V2=c(1,NA,2,2,NA),
       V3=c(1,2,2,1,NA), V4=c(NA, NA, 1,2, NA))

Подсчитайте появление «1» и «2» каждого и обоих вместе взятых:

      df %>%
  rowwise() %>%
  mutate(count_1 = sum(c_across(V1:V4) == 1, na.rm = TRUE),
         count_2 = sum(c_across(V1:V4) == 2, na.rm = TRUE),
         count_12 = sum(c_across(V1:V4) %in% 1:2, na.rm = TRUE)) %>%
  ungroup()

что дает таблицу:

           V1    V2    V3    V4 count_1 count_2 count_12
1     1     1     1    NA       3       0        3
2     1    NA     2    NA       1       1        2
3     2     2     2     1       1       3        4
4     1     2     1     2       2       2        4
5    NA    NA    NA    NA       0       0        0

Пытаясь найти что-то похожее на Count из SPSS в R выглядит следующим образом:

`df <- data.frame(a=c(1,1,NA,2,3,9),b=c(1,2,3,2,NA,1))` #Dummy data with NAs 

`df %>% 
  dplyr::mutate(count = rowSums( #this allows calculate sum across rows
    dplyr::select(., #Slicing on .  
                  dplyr::one_of( #within select use one_of by clarifying which columns your want
                    c('a','b'))), na.rm = T)) #once the columns are specified, that's all you need, na.rm is cherry on top

Вот так выглядит результат

> df a b count 1 1 1 2 2 1 2 3 3 NA 3 3 4 2 2 4 5 3 NA 3 6 9 1 10

Надеюсь, это поможет:-)

Другие вопросы по тегам