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?
3 Réponses :
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
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.
Vous pouvez essayer ceci
(extensible pour vérifier plus de deux lignes si vous supprimez le Si vous ne voulez pas créer de nouvelles colonnes & 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)
)
mais remplacez les colonnes h1, h2, ...-, supprimez simplement le nom dans la list-call.
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
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))oudata.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 a > 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'utilisercolSumsest 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 commee1 == 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-packagetidyverse; 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.