1
votes

comment appliquer la fonction à chaque colonne dans le dataframe de R

Je veux appliquer une fonction à chaque colonne de R. Supposons que ce qui suit soit le dataframe avec (3xn):

df <- data.frame(
  h1 = c(1,2,3),
  h2 = c(2,3,1),
  h3 = c(3,2,1),
  h4 = c(1,2,3),
  h5 = c(1,2,3)
)
rownames(df) <- c("e1", "e2", "e3")
df
#    h1 h2 h3 h4 h5
# e1  1  2  3  1  1
# e2  2  3  2  2  2
# e3  3  1  1  3  3

si nous voulons vérifier si les 2 premiers éléments supposent (e1 = = 1, e2 == 2) pour chaque colonne (h1, h2 ...). Comment pourrions-nous appliquer la fonction de vérification à chaque colonne du bloc de données?


5 commentaires

Veuillez ne pas publier une image de code / données / erreurs: il ne peut pas être copié ou recherché (SEO), il casse les lecteurs d'écran et il peut ne pas convenir à certains appareils mobiles. Réf: meta.stackoverflow.com/a/285557/3358272 (et xkcd.com/2116 ). Veuillez simplement inclure le code ou les données (par exemple, dput (head (x)) ou data.frame (...) ) directement.


@ r2evans Quand il a été publié pour la première fois, ce n'était pas une image. Je pense qu'il a été édité


Vous ne disposez pas encore des autorisations nécessaires pour afficher une image. Mais si vous le mettez avec cette intention, quelqu'un modifie généralement votre question pour afficher l'image. Mais ce que je veux dire est qu’une image de données ne fait aucun bien à moi (et à d’autres), et je ne passerai catégoriquement pas de temps à transcrire les données d’une image en code ou en données utilisables. Il est tout aussi facile (peut-être plus facile) pour vous de copier du texte depuis votre console R et de le coller dans un bloc de code que d'obtenir une capture d'écran et de la publier en tant qu'image.


En général, "appliquer la fonction à chaque colonne" est littéralement lapply (dataframe, myfunc) . La suggestion d'akrun d'utiliser colSums est l'un des cas spéciaux, et est beaucoup plus efficace dans cette situation.


Pour mémoire, après avoir pris les exemples de données dans la réponse de alex_jwb90 (et être passé à data.frame ), cette question est un peu plus facilement reproductible. J'ai gardé les noms de lignes uniquement parce que vous les avez référencés comme e1 == 1 , etc. notez que de nombreuses opérations sur les cadres ne conserveront pas les noms de lignes, y compris à peu près tout dans le méta-package tidyverse ; donc, bien que je puisse voir une certaine utilité dans les noms de lignes en général (et cela peut être une opinion polarisante pour certains), je ne les utilise normalement pas ou ne me fie pas à eux.


3 Réponses :


3
votes

Sous-définissez les lignes des données en fonction de row.names ou de head , comparez == avec un vecteur de valeurs, obtenez les colSums de la matrice logique qui en dérive et vérifier si cela est égal à 2 c'est-à-dire si les deux éléments sont TRUE pour chaque colonne

apply(head(mat, 2), 2, function(x) all(x  == c(1, 2)))

Ou avec apply , boucler sur les colonnes (MARGIN = 2 ), appliquer la fonction (appel de fonction anonyme) et vérifier si tous sont TRUE de la comparaison

colSums(mat[c("e1", "e2"),] == c(1, 2))==2


3 commentaires

Merci pour votre réponse. Mais, je dois faire quelque chose comme suivant et donc utiliser la fonction apply / lapply / sapply dans R: rank.shape = function (x) {# i varie ici de 1 à 5, qui est le nombre de colonnes df = NA si (x [1,] [i] == 2 && x [2,] [i] == 1) {// ....} sinon si (x [1,] [i] == 2 && x [ 2,] [i] == 1.5) {// ....)} list.shape = lapply (matrixRanks [1,], rank.shape)


@ChimiWangmo j'ai répondu à la question posée


Chimi, autant de code dans un commentaire ne se formate pas toujours bien. De plus, vous dites explicitement que vous devez utiliser l'une des fonctions de la famille apply, veuillez donc être clair dans votre question. L'utilisation de "apply" comme verbe n'indique pas clairement l'utilisation de apply comme fonction.



0
votes

Vous pouvez essayer ceci (extensible pour vérifier plus de deux lignes si vous supprimez le & row_number () )

library(dplyr)

df = tibble(
  h1 = c(1,2,3),
  h2 = c(2,3,1),
  h3 = c(3,2,1),
  h4 = c(1,2,3),
  h5 = c(1,2,3)
)

df %>%
  mutate_all(
    list(equals_rownum = ~.==row_number() & row_number() <= 2)
  )

Si vous ne voulez pas créer de nouvelles colonnes _equals_rownum mais remplacez les colonnes h1, h2, ...-, supprimez simplement le nom dans la list-call.


0 commentaires

3
votes

En utilisant les données de @ alex_jwb90,

lapply(df, function(a) a[1:2] == 1:2)
# $h1
# [1] TRUE TRUE
# $h2
# [1] FALSE FALSE
# $h3
# [1] FALSE  TRUE
# $h4
# [1] TRUE TRUE
# $h5
# [1] TRUE TRUE

lapply(df, function(a) all(a[1:2] == 1:2))
# $h1
# [1] TRUE
# $h2
# [1] FALSE
# $h3
# [1] FALSE
# $h4
# [1] TRUE
# $h5
# [1] TRUE

sapply(df, function(a) all(a[1:2] == 1:2))
#    h1    h2    h3    h4    h5 
#  TRUE FALSE FALSE  TRUE  TRUE 


0 commentaires