Je m'excuse si cette question a déjà été posée (je sais qu'il y a une question similaire ici ), mais je me débat avec cela depuis des heures maintenant et je ne trouve pas de solution.

Voici un échantillon de mes cadres de données:

mydf1 <- structure(list(r_id = c(574111L, 291615L, 328543L),
  a_name = c("Daft Punk", "Daft Punk", "Daft Punk"),
  r_title = c("Discovery", "TRON: Legacy", "Random Access Memories")),
  .Names = c("r_id", "a_name", "r_title"),
  row.names = c(NA, 3L),
  class = "data.frame")

mydf2 <- structure(list(date_y = c(2015, 2015, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014),
  date_m = c(3, 3, 6, 5, 5, 5, 5, 5, 5, 4),
  date_d = c(28, 21, 7, 31, 24, 17, 17, 10, 3, 26),
  a_name = c("Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk", "Daft Punk"),
  r_title = c("Discovery", "Discovery", "Random Access Memories", "Random Access Memories", "Random Access Memories", "Random Access Memories", "Discovery", "Random Access Memories", "Random Access Memories", "Random Access Memories"),
  b_rank = c(110, 117, 114, 104, 95, 64, 99, 51, 63, 45),
  l_rank = c(4.52178857704904, 4.44265125649032, 4.47733681447821, 4.58496747867057, 4.67282883446191, 4.92725368515721, 4.63472898822964, 5.01727983681492, 4.93447393313069, 5.05624580534831)),
  .Names = c("date_y", "date_m", "date_d", "a_name", "r_title", "b_rank", "l_rank"),
  row.names = c(NA, -10L),
  class = "data.frame")

Je voudrais ajouter une colonne à mydf1, contenant la valeur renvoyée par la fonction suivante:

myfunction1 <- function(this_a, this_r){
tot_w <- subset(mydf2, a_name == this_a & r_title == this_r)
return(sum(tot_w$l_rank, na.rm = TRUE))}

Étant nouveau dans R et toujours habitué à travailler avec des boucles dans VBA, l'idée dans mon esprit est que la fonction prend la valeur de a_name et r_title dans mydf1 comme arguments, va à { {X3}} et sous-ensembles les lignes correspondantes, le cas échéant, additionne ensuite les valeurs dans l_rank. Le résultat devrait être:

mydf3 <- structure(list(r_id = c(574111L, 291615L, 328543L),
  a_name = c("Daft Punk", "Daft Punk", "Daft Punk"),
  r_title = c("Discovery", "TRON: Legacy", "Random Access Memories"),
  l_rank = c("13.59917", "0.000000", "33.67039")),
  .Names = c("r_id", "a_name", "r_title", "l_rank"),
  row.names = c(NA, 3L),
  class = "data.frame")

Une solution est la suivante:

mydf3 <- mydf1 %>%
  rowwise() %>%
  mutate(l_rank = myfunction1(a_name, r_title))

Cela semble fonctionner, mais étant donné que je dois l'exécuter sur un grand nombre de lignes, je soupçonne que c'est trop lent. En regardant la réponse à la question ci-dessus, j'ai essayé d'utiliser apply comme suit:

mydf3 <- mydf1
mydf3$l_rank <- apply(mydf1, 1,
  function(x, y) myfunction1(mydf1["a_name"], mydf1["r_title"]))

Mais cela ne produit pas le résultat escompté. J'ai également essayé d'utiliser data.table comme ceci:

mydf3 <- data.table(mydf1)
mydf3[, l_rank := myfunction1(mydf3$a_name, mydf3$r_title)]

Aussi en vain. Je serais très reconnaissant si quelqu'un pouvait me dire ce que je fais mal parce que cela me donne mal à la tête.

MODIFIER Notez que les lignes de mydf1 peuvent être des doublons.

r
0
Michele 17 janv. 2017 à 17:01

2 réponses

Meilleure réponse

Si vous souhaitez continuer dplyr, vous pouvez utiliser les éléments suivants:

sumdf <- mydf2 %>% group_by(a_name, r_title) %>% 
  summarise(l_rank=sum(l_rank, na.rm=TRUE))

mydf1 %>% merge(sumdf, by=c('a_name','r_title'), all.x=TRUE)

Je n'utilise pas la fonction mais j'utilise l'agrégation avec dplyr::summarise

Ou dans un seul tuyau comme mentionné dans les commentaires:

mydf2 %>% group_by(a_name, r_title) %>% 
  summarise(l_rank=sum(l_rank, na.rm=TRUE)) %>%
  right_join(mydf1, by = c('a_name','r_title'))
3
Wietze314 19 janv. 2017 à 13:26

Nous pouvons utiliser la jointure data.table après avoir converti le 'data.frame' en 'data.table' (setDT).

library(data.table)
mydf1[, l_rank := setDT(mydf2)[mydf1, .(l_rank=sum(l_rank)),
          on = .(a_name, r_title), by = .EACHI]$l_rank]
#     r_id    a_name                r_title   l_rank
#1: 574111 Daft Punk              Discovery 13.59917
#2: 291615 Daft Punk           TRON: Legacy       NA
#3: 328543 Daft Punk Random Access Memories 33.67039
1
akrun 17 janv. 2017 à 16:48