#r #data-manipulation
#r #манипулирование данными
Вопрос:
Я работаю над фреймом данных, который нравится:
groups . values
a . 1
a . 1
a 2
b . 2
b . 3
b . 3
c . 4
c . 5
c . 6
d . 6
d . 7
d . 2
Проблема в том, чтобы превратить это во что-то вроде:
groups . values
a . 1
a . 1
b . 3
b . 3
c . 4
c . 5
d . 7
Я хочу сохранить строки, значения которых встречаются только в ОДНОЙ группе. Например, значение 2 удаляется, потому что оно встречается в трех разных группах, но значение 1 сохраняется, хотя оно встречается дважды ТОЛЬКО в ОДНОЙ группе.
Есть ли какие-либо функции из пакета dplyr, которые могут справиться с этой проблемой? или я должен написать свою собственную функцию?
Комментарии:
1. Что у вас есть на данный момент?
2. Я пробовал что-то вроде «DATAFRAME %>% group_by (группы) %>% distinct (значения)», но он сохраняет только уникальные значения в каждой группе.
Ответ №1:
Как вы просили dplyr
решение:
df %>% group_by(values) %>% filter(n_distinct(groups) == 1)
# # A tibble: 7 x 2
# # Groups: values [5]
# groups values
# <chr> <int>
#1 a 1
#2 a 1
#3 b 3
#4 b 3
#5 c 4
#6 c 5
#7 d 7
с
df <- structure(list(groups = c("a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d", "d"),
values = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 5L, 6L, 6L, 7L, 2L)),
row.names = c(NA, -12L), class = "data.frame")
Ответ №2:
Сгруппируйте по values
и посмотрите, содержит ли столбец groups
только один элемент. Это можно сделать с помощью ave
.
i <- as.logical(with(df1, ave(as.numeric(groups), values, FUN = function(x) length(unique(x)) == 1)))
df1[i, ]
# groups values
#1 a 1
#2 a 1
#5 b 3
#6 b 3
#7 c 4
#8 c 5
#11 d 7
Данные в dput
формате.
df1 <-
structure(list(groups = structure(c(1L, 1L, 1L, 2L,
2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("a", "b",
"c", "d"), class = "factor"), values = c(1L, 1L, 2L,
2L, 3L, 3L, 4L, 5L, 6L, 6L, 7L, 2L)),
class = "data.frame", row.names = c(NA, -12L))
Ответ №3:
x[x$values %in% names(which(colSums(table(x)>0)==1)),]
где
x = structure(list(groups = c("a", "a", "a", "b", "b", "b", "c",
"c", "c", "d", "d", "d"), values = c(1L, 1L, 2L, 2L, 3L, 3L,
4L, 5L, 6L, 6L, 7L, 2L)), row.names = c(NA, -12L), class = "data.frame")
или data.table
решение:
setDT(x)[, .SD[uniqueN(groups)==1], values]
Ответ №4:
Использование sqldf
пакета для вашего исходного фрейма данных df
:
library(sqldf)
result <- sqldf("SELECT * FROM df
WHERE `values` IN (
SELECT `values` from (
SELECT `values`, groups, count(*) as num from df
GROUP BY `values`, groups) t
GROUP BY `values`
HAVING COUNT(1) = 1
)")