Выявление различий в строках с помощью группирования по столбцу - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть этот воспроизводимый кадр данных:

df <- data.frame(ID = c("A", "A", "B", "B", "B","C", "C", "D"), cost = c("0.5", "0.4", "0.7", "0.8", "0.5", "1.3", "1.3", "2.6"))

Я пытаюсь сгруппировать идентификатор, чтобы проверить, есть ли различия в столбце cost, и обновить новый столбец с именем Test diff* 1006.*

Промежуточный вывод

  ID cost Testdiff
1  A  0.5        Y
2  A  0.4        Y
3  B  0.7        Y
4  B  0.8        Y
5  B  0.5        Y
6  C  1.3        N
7  C  1.3        N
8  D  2.6        N

Я смотрю на примере использования dplyr, но я не уверен, является ли match правильной функцией.

df %>% group_by(ID) %>% mutate(Testdiff = ifelse(match(cost) == T, "Y", "N"))

Как только это будет завершено, я хочу сохранить 1-ую строку уникального идентификатора, давая мне этот вывод

  ID cost Testdiff
1  A  0.5        Y
2  B  0.7        Y
3  C  1.3        N
4  D  2.6        N

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Поскольку у нас уже есть dplyr и base R, почему бы не добавить data.table:

library(data.table)
setDT(df)[, .(cost = cost[1], testdiff = uniqueN(cost) > 1), by = ID]

   ID cost testdiff
1:  A  0.5     TRUE
2:  B  0.7     TRUE
3:  C  1.3    FALSE
4:  D  2.6    FALSE
0 голосов
/ 14 февраля 2019

Другая возможность tidyverse может быть:

df %>%
 group_by(ID) %>%
 mutate(Testdiff = ifelse(all(cost == first(cost)), "N", "Y")) %>%
 filter(row_number() == 1)

  ID    cost  Testdiff
  <fct> <fct> <chr>   
1 A     0.5   Y       
2 B     0.7   Y       
3 C     1.3   N       
4 D     2.6   N   

Или:

df %>%
 group_by(ID) %>%
 mutate(Testdiff = ifelse(all(cost == first(cost)), "N", "Y")) %>%
 top_n(1, wt = desc(row_number()))
0 голосов
/ 14 февраля 2019

Мы могли бы использовать n_distinct, а затем slice

library(dplyr)

df %>%
  group_by(ID) %>%
  mutate(Testdiff = n_distinct(cost) > 1) %>%
  slice(1)

#    ID    cost  Testdiff
#   <fct> <fct> <lgl>   
#1   A     0.5   TRUE    
#2   B     0.7   TRUE    
#3   C     1.3   FALSE   
#4   D     2.6   FALSE   

Если вы хотите, чтобы вывод был "Y" / "N" вместо ИСТИНА / ЛОЖЬ

df %>%
 group_by(ID) %>%
 mutate(Testdiff = ifelse(n_distinct(cost) > 1, "Y", "N")) %>%
 slice(1)

Мы могли бы использовать ave и aggregate, чтобы решить ее, используя базу R

df$Testdiff <- ifelse(with(df, ave(cost, ID, FUN = function(x) 
                      length(unique(x)))) > 1, "Y", "N")

aggregate(.~ID, df, head, n = 1)


#  ID cost Testdiff
#1  A  0.5        Y
#2  B  0.7        Y
#3  C  1.3        N
#4  D  2.6        N
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...