Как проверить, сколько символов столбцов можно найти

У меня есть набор данных с 4 столбцами, содержащими имена, где количество имен и порядок имен различаются между столбцами. Некоторые столбцы могут также содержать одно и то же имя дважды или более. Это выглядит так:

df<- data.frame(x1=c("Ben","Alex","Tim", "Lisa", "MJ","NA", "NA","NA","NA"), 
x2=c("Ben","Paul","Tim", "Linda", "Alex", "MJ", "Lisa", "Ken","NA"), 
x3=c("Tomas","Alex","Ben", "Paul", "MJ", "Tim", "Ben", "Alex", "Linda"), 
x4=c("Ben","Alex","Tim", "Lisa", "MJ", "Ben", "Barbara","NA", "NA"))

Теперь мне нужно сначала извлечь уникальные имена в наборе данных. Я сделал это с помощью следующего кода:

u<- as.vector(unique(unlist(df)))

Во-вторых, мне нужно найти имена, которые можно найти во всех 4 столбцах (имена класса A), в 3 из 4 столбцов (имена класса B) и в 2 из 4 столбцов (имена класса C).

Вот где я застреваю. Я могу извлечь только имена, содержащиеся во всех 4 столбцах, используя:

n<- ifelse(u%in%df$x1 & u%in%df$x2 & u%in%df$x3 & 
               u%in%df$x4", A, B)

Так, например, Ben будет именем класса A, потому что его можно найти во всех 4 столбцах, а Lisa будет именем класса B, потому что его можно найти только в 3 из 4 столбцов.

Name Class
Ben    A
Lisa   B

Есть ли лучший способ классифицировать уникальные имена по количеству столбцов, в которых они могут быть найдены, и как это можно сделать для имен классов B и C?

Заранее спасибо!


person ZayzayR    schedule 04.08.2020    source источник
comment
Простите за это! Я добавил несколько строк NA для более коротких столбцов. Так что теперь это больше похоже на исходные данные.   -  person ZayzayR    schedule 04.08.2020
comment
stackoverflow.com/questions/63235393/ Вы создали тему с похожим вопросом. Смотрите ответ. Это подходит?   -  person Yuriy Saraykin    schedule 04.08.2020
comment
table(unlist(lapply(df, levels))) (если это факторы) или table(unlist(lapply(df, unique))) (если это символы) - другой вариант   -  person David Arenburg    schedule 04.08.2020


Ответы (3)


Вы можете получить данные в длинном формате и для каждого имени найти, сколько уникальных столбцов оно встречается:

library(dplyr)

df %>%
  tidyr::pivot_longer(cols = everything(), values_drop_na = TRUE) %>%
  group_by(value) %>%
  summarise(count = n_distinct(name))

#   value   count
#   <chr>   <int>
# 1 Alex        4
# 2 Barbara     1
# 3 Ben         4
# 4 Ken         1
# 5 Linda       2
# 6 Lisa        3
# 7 MJ          4
# 8 NA          3
# 9 Paul        2
#10 Tim         4
#11 Tomas       1

Здесь вы получаете "NA" на выходе, потому что это строка. Если в ваших данных есть настоящие NA, они будут удалены из-за values_drop_na = TRUE.

person Ronak Shah    schedule 04.08.2020
comment
Привет, большое спасибо! Это идеальное решение моей проблемы! Как вы думаете, я могу сделать из этого цикл for и применить его к нескольким наборам данных, скажем, к 5 (df1, df2, df3, df4, df5) сразу? Вы также знаете решение этой проблемы? - person ZayzayR; 04.08.2020
comment
Поместите приведенный выше код в функцию (скажем, fun). Затем поместите все фреймы данных в список lst_data <- list(df1, df2...) и используйте map(lst_data, fun). - person Ronak Shah; 04.08.2020

Вот идея с помощью базы R. Мы перебираем уникальные элементы и берем rowSums, когда фрейм данных совпадает с каждым именем. Максимальный результат - это ваш ожидаемый результат

sapply(unique(c(t(df))), function(i) max(rowSums(df == i)))

#  Ben Tomas  Alex  Paul   Tim  Lisa Linda    MJ 
#    3     1     3     1     3     2     1     3 
person Sotos    schedule 04.08.2020
comment
Спасибо за ответ! Но мне нужно знать, в каком количестве столбцов можно найти хотя бы один раз имена. Таким образом, для Бена это должно быть 4, потому что имя Бен можно найти во всех 4 столбцах (хотя бы один раз). Вы знаете решение этой проблемы? - person ZayzayR; 04.08.2020

Простая базовая опция R с использованием aggregate + stack

aggregate(.~values,unique(stack(df)),length)

такой, что

> aggregate(.~values,unique(stack(df)),length)
    values ind
1     Alex   4
2  Barbara   1
3      Ben   4
4      Ken   1
5    Linda   2
6     Lisa   3
7       MJ   4
8       NA   3
9     Paul   2
10     Tim   4
11   Tomas   1
person ThomasIsCoding    schedule 04.08.2020
comment
Это не работает в моем сеансе R. Я получаю Error in stack.data.frame(df) : no vector columns were selected - person David Arenburg; 04.08.2020
comment
@DavidArenburg Это странно ... Какая у вас версия R? У меня 4.0.2 в Win 10 - person ThomasIsCoding; 04.08.2020
comment
Ага, наверное это R версия, до 4 еще не переходил - person David Arenburg; 04.08.2020