Используйте dplyr для создания консенсусного столбца - PullRequest
1 голос
/ 15 мая 2019

У меня есть датафрейм:

  Groups    Name    Category    value
        G1  A   cat1    20
        G1  A   cat2    1
        G1  B   cat3    21
        G1  B   cat3    23
        G2  B   cat4    32
        G2  C   cat2    23
        G2  C   cat2    21

и я хотел добавить новый столбец consensus_category, например:

Groups  Name    Category    value   consensus_category
G1  A   cat1    20  cat2
G1  A   cat2    1   cat2
G1  B   cat3    21  cat2
G1  B   cat3    23  cat2
G2  A   cat4    32  cat4
G2  C   cat2    23  cat4
G2  C   cat2    21  cat4

идея заключается в том, что у меня есть vector = c("A") с соответствующим конкретным именем в кадре данных

и из этого имени я хотел бы написать соответствующий Category для всех других строк в том же Groups, но если между двумя Categories есть ex-aequo, чем победитель - category с самым низким Value. (как в:

G1  A   cat1    20  cat2
G1  A   cat2    1   cat2

cat2 побед, потому что 1 < 20

Я пытался:

df %>%
  group_by(Groups) %>%
  add_count(Category) %>%
  top_n(1, n) %>%
  top_n(-1, Value) %>%
  distinct(consensus_category = Category) %>%
  right_join(df) 

но я не знаю, как указать, что я хочу в качестве консенсуса указать значение в векторе (A).

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Опция с data.table

library(data.table)
setDT(df)[, consensus_category := Category[value ==
      min(value[Name == vec])],  Groups]
df
#   Groups Name Category value consensus_category
#1:     G1    A     cat1    20               cat2
#2:     G1    A     cat2     1               cat2
#3:     G1    B     cat3    21               cat2
#4:     G1    B     cat3    23               cat2
#5:     G2    A     cat4    32               cat4
#6:     G2    C     cat2    23               cat4
#7:     G2    C     cat2    21               cat4

data

df <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
"G2"), Name = c("A", "A", "B", "B", "A", "C", "C"), Category = 
c("cat1", "cat2", "cat3", "cat3", "cat4", "cat2", "cat2"), value = 
c(20L, 1L, 21L, 23L, 32L, 23L, 21L)), class = "data.frame", row.names = 
c(NA, -7L))
1 голос
/ 15 мая 2019

Используя dplyr, вы можете найти Name с vec в группе, получить минимум value и извлечь из него соответствующее Category.Предполагается, что в каждом Groups есть хотя бы одно значение vec.

library(dplyr)

vec <- "A"

df %>%
  group_by(Groups) %>%
  mutate(consensus_category = Category[value == min(value[Name == vec])])

#  Groups Name  Category value consensus_category
#  <fct>  <fct> <fct>    <int> <fct>             
#1 G1     A     cat1        20 cat2              
#2 G1     A     cat2         1 cat2              
#3 G1     B     cat3        21 cat2              
#4 G1     B     cat3        23 cat2              
#5 G2     A     cat4        32 cat4              
#6 G2     C     cat2        23 cat4              
#7 G2     C     cat2        21 cat4      

Если в vec есть несколько значений, вам может потребоваться Name %in% vec вместо ==.

data

df <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
"G2"), Name = c("A", "A", "B", "B", "A", "C", "C"), Category = 
c("cat1", "cat2", "cat3", "cat3", "cat4", "cat2", "cat2"), value = 
c(20L, 1L, 21L, 23L, 32L, 23L, 21L)), class = "data.frame", row.names = 
c(NA, -7L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...