Подсчет вхождений значения в наборе переменных в 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
Надеюсь, это поможет:-)