J'ai supprimé le nom à supprimer. Ne semble pas ajouter grand - chose, et alors que Hadley est répertorié comme un auteur du paquet Kirill Müller est répertorié comme créateur et mainteneur .
Je trouve que la réorganisation en utilisant setcolorderconjointement avec les numéros de colonne (par opposition à leurs noms) est également très utile, car une fois que le nombre de colonnes devient très grand, vous pouvez commencer à utiliser seqet repà faire la plupart du travail. De plus, des opérateurs arithmétiques peuvent être utilisés. Par exemplesetcolorder(data, c(1, (num_cols -2), (num_cols -1), num_cols, seq(from = 2, to = (num_cols - 3))))
n1k31t4
1
Je devrais mentionner, setcolorderest destiné à un data.table, pas à un data.frame!
n1k31t4
21
Vous pouvez réorganiser les colonnes avec [ou présenter les colonnes dans l'ordre que vous souhaitez.
d <- data.frame(a=1:4, b=5:8, c=9:12)
target <- which(names(d) == 'b')[1]
cbind(d[,1:target,drop=F], data.frame(d=12:15), d[,(target+1):length(d),drop=F])
a b d c
115129226131033714114481512
C'est une excellente réponse. Mais je dois admettre que c'est aussi un excellent exemple de la raison pour laquelle R peut être difficile pour les débutants.
tumultous_rooster
2
Cela étant dit, je pense que @ ashah57 a une réponse beaucoup plus simple et plus claire ci-dessous. Pas besoin de se faire une idée de quelque chose comme ça
tumultous_rooster
12
En supposant que cela csuit toujours immédiatement b, ce code ajoutera une colonne après bn'importe où bdans votre data.frame.
> test <- data.frame(a=1,b=1,c=1)
> test
a b c
1111
> bspot <- which(names(test)=="b")
> data.frame(test[1:bspot],d=2,test[(bspot+1):ncol(test)])
a b d c
11121
Voici une manière rapide et sale d'insérer une colonne à une position spécifique sur un bloc de données. Dans mon cas, j'ai 5 colonnes dans le bloc de données d'origine: c1, c2, c3, c4, c5et je vais insérer une nouvelle colonne c2bentre c2et c3.
3) Réorganisez le bloc de données en fonction des index de colonne. Dans mon cas, je souhaite insérer la nouvelle colonne (6) entre les colonnes existantes 2 et 3. Je le fais en adressant les colonnes de mon bloc de données en utilisant le vecteur c(1:2, 6, 3:5)qui équivaut à c(1, 2, 6, 3, 4, 5).
Pour ce que ça vaut, j'ai écrit une fonction pour faire ceci:
[supprimé]
J'ai maintenant mis à jour cette fonction avec beforeet afterfonctionnalité et par défaut placeà 1. Il a également la compatibilité de la table de données:
###### FUNCTION: InsertDFCol(colName, colData, data, place = 1, before, after)# DESCRIPTION: Takes in a data, a vector of data, a name for that vector and a place to insert this vector into# the data frame as a new column. If you put place = 3, the new column will be in the 3rd position and push the current# 3rd column up one (and each subsuquent column up one). All arguments must be set. Adding a before and after# argument that will allow the user to say where to add the new column, before or after a particular column.# Please note that if before or after is input, it WILL override the place argument if place is given as well. Also, place# defaults to adding the new column to the front.#####
InsertDFCol <- function(colName, colData, data, place = 1, before, after) {
# A check on the place argument.if (length(names(data)) < place) stop("The place argument exceeds the number of columns in the data for the InsertDFCol function. Please check your place number")
if (place <= 0 & (!missing(before) | !(missing(after)))) stop("You cannot put a column into the 0th or less than 0th position. Check your place argument.")
if (place %% 1 != 0 & (!missing(before) | !(missing(after)))) stop("Your place value was not an integer.")
if (!(missing(before)) & !missing(after)) stop("You cannot designate a before AND an after argument in the same function call. Please use only one or the other.")
# Data Table compatability.
dClass <- class(data)
data <- as.data.frame(data)
# Creating booleans to define whether before or after is given.
useBefore <- !missing(before)
useAfter <- !missing(after)
# If either of these are true, then we are using the before or after argument, run the following code.if (useBefore | useAfter) {
# Checking the before/after argument if given. Also adding regular expressions.if (useBefore) { CheckChoice(before, names(data)) ; before <- paste0("^", before, "$") }
if (useAfter) { CheckChoice(after, names(data)) ; after <- paste0("^", after, "$") }
# If before or after is given, replace "place" with the appropriate number.if (useBefore) { newPlace <- grep(before, names(data)) ; if (length(newPlace) > 1) { stop("Your before argument matched with more than one column name. Do you have duplicate column names?!") }}
if (useAfter) { newPlace <- grep(after, names(data)) ; if (length(newPlace) > 1) { stop("Your after argument matched with more than one column name. Do you have duplicate column names?!") }}
if (useBefore) place <- newPlace # Overriding place.if (useAfter) place <- newPlace + 1# Overriding place.
}
# Making the new column.
data[, colName] <- colData
# Finding out how to reorder this.# The if statement handles the case where place = 1.
currentPlace <- length(names(data)) # Getting the place of our data (which should have been just added at the end).if (place == 1) {
colOrder <- c(currentPlace, 1:(currentPlace - 1))
} elseif (place == currentPlace) { # If the place to add the new data was just at the end of the data. Which is stupid...but we'll add support anyway.
colOrder <- 1:currentPlace
} else { # Every other case.
firstHalf <- 1:(place - 1) # Finding the first half on columns that come before the insertion.
secondHalf <- place:(currentPlace - 1) # Getting the second half, which comes after the insertion.
colOrder <- c(firstHalf, currentPlace, secondHalf) # Putting that order together.
}
# Reordering the data.
data <- subset(data, select = colOrder)
# Data Table compatability.if (dClass[1] == "data.table") data <- as.data.table(data)
# Returning.return(data)
}
J'ai réalisé que je n'incluais pas non plus CheckChoice:
###### FUNCTION: CheckChoice(names, dataNames, firstWord == "Oops" message = TRUE) # DESCRIPTION: Takes the column names of a data frame and checks to make sure whatever "choice" you made (be it # your choice of dummies or your choice of chops) is actually in the data frame columns. Makes troubleshooting easier. # This function is also important in prechecking names to make sure the formula ends up being right. Use it after # adding in new data to check the "choose" options. Set firstWord to the first word you want said before an exclamation point.# The warn argument (previously message) can be set to TRUE if you only want to #####
CheckChoice <- function(names, dataNames, firstWord = "Oops", warn = FALSE) {
for (name in names) {
if (warn == TRUE) { if(!(name %in% dataNames)) { warning(paste0(firstWord, "! The column/value/argument, ", name, ", was not valid OR not in your data! Check your input! This is a warning message of that!")) } }
if (warn == FALSE) { if(!(name %in% dataNames)) { stop(paste0(firstWord, "! The column/value/argument, " , name, ", was not valid OR not in your data! Check your input!")) } }
}
}
Voici un exemple de comment déplacer une colonne de la dernière à la première position. Il se combine [avec ncol. J'ai pensé qu'il serait utile d'avoir une réponse très courte ici pour le lecteur occupé:
R n'a pas de fonctionnalité pour spécifier où une nouvelle colonne est ajoutée. Par exemple, mtcars$mycol<-'foo'. Il est toujours ajouté comme dernière colonne. En utilisant d'autres moyens (par exemple dplyr's select()), vous pouvez déplacer le mycol vers la position souhaitée. Ce n'est pas idéal et R voudra peut-être essayer de changer cela à l'avenir.
Je suggère d'utiliser dplyr::selectaprès dplyr::mutate. Il dispose de nombreux assistants pour sélectionner / désélectionner un sous-ensemble de colonnes.
Dans le contexte de cette question, l'ordre dans lequel vous sélectionnez sera reflété dans la sortie data.frame.
Lorsque vous ne pouvez pas supposer que la colonne bvient avant, cvous pouvez utiliser matchpour trouver le numéro de colonne des deux, minpour obtenir le numéro de colonne inférieur et seq_lenpour obtenir une séquence jusqu'à cette colonne. Vous pouvez ensuite utiliser cet index d'abord comme sous-ensemble positif , puis placer la nouvelle colonne d, puis utiliser à nouveau la séquence comme sous-ensemble négatif .
i <- seq_len(min(match(c("b", "c"), colnames(x))))
data.frame(x[i], d, x[-i])
#cbind(x[i], d, x[-i]) #Alternative# a b d c#1 1 4 10 7#2 2 5 11 8#3 3 6 12 9
Si vous savez que cette colonne bprécède, cvous pouvez placer la nouvelle colonne daprès b:
i <- seq_len(match("b", colnames(x)))
data.frame(x[i], d, x[-i])
# a b d c#1 1 4 10 7#2 2 5 11 8#3 3 6 12 9
Les données:
x <- data.frame(a = 1:3, b = 4:6, c = 7:9)
d <- 10:12
Réponses:
Je vous suggère d'utiliser la fonction
add_column()
dutibble
package.library(tibble) dataset <- data.frame(a = 1:5, b = 2:6, c=3:7) add_column(dataset, d = 4:8, .after = 2)
Notez que vous pouvez utiliser des noms de colonne au lieu de l'index de colonne:
add_column(dataset, d = 4:8, .after = "b")
Ou utilisez un argument
.before
plutôt que.after
si cela est plus pratique.add_column(dataset, d = 4:8, .before = "c")
la source
Ajoutez dans votre nouvelle colonne:
Ensuite, vous pouvez les réorganiser.
df <- df[, c("a", "b", "d", "c")]
la source
setcolorder
conjointement avec les numéros de colonne (par opposition à leurs noms) est également très utile, car une fois que le nombre de colonnes devient très grand, vous pouvez commencer à utiliserseq
etrep
à faire la plupart du travail. De plus, des opérateurs arithmétiques peuvent être utilisés. Par exemplesetcolorder(data, c(1, (num_cols -2), (num_cols -1), num_cols, seq(from = 2, to = (num_cols - 3))))
setcolorder
est destiné à un data.table, pas à un data.frame!Vous pouvez réorganiser les colonnes avec [ou présenter les colonnes dans l'ordre que vous souhaitez.
d <- data.frame(a=1:4, b=5:8, c=9:12) target <- which(names(d) == 'b')[1] cbind(d[,1:target,drop=F], data.frame(d=12:15), d[,(target+1):length(d),drop=F]) a b d c 1 1 5 12 9 2 2 6 13 10 3 3 7 14 11 4 4 8 15 12
la source
En supposant que cela
c
suit toujours immédiatementb
, ce code ajoutera une colonne aprèsb
n'importe oùb
dans votre data.frame.> test <- data.frame(a=1,b=1,c=1) > test a b c 1 1 1 1 > bspot <- which(names(test)=="b") > data.frame(test[1:bspot],d=2,test[(bspot+1):ncol(test)]) a b d c 1 1 1 2 1
Ou peut-être plus naturellement:
data.frame(append(test, list(d=2), after=match("b", names(test))))
la source
Créez un exemple de data.frame et ajoutez-y une colonne.
df = data.frame(a = seq(1, 3), b = seq(4,6), c = seq(7,9)) df['d'] <- seq(10,12) df a b c d 1 1 4 7 10 2 2 5 8 11 3 3 6 9 12
Réorganiser par index de colonne
df[, colnames(df)[c(1:2,4,3)]]
ou par nom de colonne
df[, c('a', 'b', 'd', 'c')]
Le résultat est
a b d c 1 1 4 10 7 2 2 5 11 8 3 3 6 12 9
la source
Vous souhaitez ajouter la colonne z à l'ancien bloc de données (old.df) défini par les colonnes x et y.
z = rbinom(1000, 5, 0.25) old.df <- data.frame(x = c(1:1000), y = rnorm(1:1000)) head(old.df)
Définissez un nouveau bloc de données appelé new.df
new.df <- data.frame(x = old.df[,1], z, y = old.df[,2]) head(new.df)
la source
Voici une manière rapide et sale d'insérer une colonne à une position spécifique sur un bloc de données. Dans mon cas, j'ai 5 colonnes dans le bloc de données d'origine:
c1, c2, c3, c4, c5
et je vais insérer une nouvelle colonnec2b
entrec2
etc3
.1) Créons d'abord la trame de données de test:
> dataset <- data.frame(c1 = 1:5, c2 = 2:6, c3=3:7, c4=4:8, c5=5:9) > dataset c1 c2 c3 c4 c5 1 1 2 3 4 5 2 2 3 4 5 6 3 3 4 5 6 7 4 4 5 6 7 8 5 5 6 7 8 9
2) Ajoutez la nouvelle colonne
c2b
à la fin de notre bloc de données:> dataset$c2b <- 10:14 > dataset c1 c2 c3 c4 c5 c2b 1 1 2 3 4 5 10 2 2 3 4 5 6 11 3 3 4 5 6 7 12 4 4 5 6 7 8 13 5 5 6 7 8 9 14
3) Réorganisez le bloc de données en fonction des index de colonne. Dans mon cas, je souhaite insérer la nouvelle colonne (6) entre les colonnes existantes 2 et 3. Je le fais en adressant les colonnes de mon bloc de données en utilisant le vecteur
c(1:2, 6, 3:5)
qui équivaut àc(1, 2, 6, 3, 4, 5)
.> dataset <- dataset[,c(1:2, 6, 3:5)] > dataset c1 c2 c2b c3 c4 c5 1 1 2 10 3 4 5 2 2 3 11 4 5 6 3 3 4 12 5 6 7 4 4 5 13 6 7 8 5 5 6 14 7 8 9
Là!
la source
Pour ce que ça vaut, j'ai écrit une fonction pour faire ceci:
[supprimé]
J'ai maintenant mis à jour cette fonction avec
before
etafter
fonctionnalité et par défautplace
à 1. Il a également la compatibilité de la table de données:##### # FUNCTION: InsertDFCol(colName, colData, data, place = 1, before, after) # DESCRIPTION: Takes in a data, a vector of data, a name for that vector and a place to insert this vector into # the data frame as a new column. If you put place = 3, the new column will be in the 3rd position and push the current # 3rd column up one (and each subsuquent column up one). All arguments must be set. Adding a before and after # argument that will allow the user to say where to add the new column, before or after a particular column. # Please note that if before or after is input, it WILL override the place argument if place is given as well. Also, place # defaults to adding the new column to the front. ##### InsertDFCol <- function(colName, colData, data, place = 1, before, after) { # A check on the place argument. if (length(names(data)) < place) stop("The place argument exceeds the number of columns in the data for the InsertDFCol function. Please check your place number") if (place <= 0 & (!missing(before) | !(missing(after)))) stop("You cannot put a column into the 0th or less than 0th position. Check your place argument.") if (place %% 1 != 0 & (!missing(before) | !(missing(after)))) stop("Your place value was not an integer.") if (!(missing(before)) & !missing(after)) stop("You cannot designate a before AND an after argument in the same function call. Please use only one or the other.") # Data Table compatability. dClass <- class(data) data <- as.data.frame(data) # Creating booleans to define whether before or after is given. useBefore <- !missing(before) useAfter <- !missing(after) # If either of these are true, then we are using the before or after argument, run the following code. if (useBefore | useAfter) { # Checking the before/after argument if given. Also adding regular expressions. if (useBefore) { CheckChoice(before, names(data)) ; before <- paste0("^", before, "$") } if (useAfter) { CheckChoice(after, names(data)) ; after <- paste0("^", after, "$") } # If before or after is given, replace "place" with the appropriate number. if (useBefore) { newPlace <- grep(before, names(data)) ; if (length(newPlace) > 1) { stop("Your before argument matched with more than one column name. Do you have duplicate column names?!") }} if (useAfter) { newPlace <- grep(after, names(data)) ; if (length(newPlace) > 1) { stop("Your after argument matched with more than one column name. Do you have duplicate column names?!") }} if (useBefore) place <- newPlace # Overriding place. if (useAfter) place <- newPlace + 1 # Overriding place. } # Making the new column. data[, colName] <- colData # Finding out how to reorder this. # The if statement handles the case where place = 1. currentPlace <- length(names(data)) # Getting the place of our data (which should have been just added at the end). if (place == 1) { colOrder <- c(currentPlace, 1:(currentPlace - 1)) } else if (place == currentPlace) { # If the place to add the new data was just at the end of the data. Which is stupid...but we'll add support anyway. colOrder <- 1:currentPlace } else { # Every other case. firstHalf <- 1:(place - 1) # Finding the first half on columns that come before the insertion. secondHalf <- place:(currentPlace - 1) # Getting the second half, which comes after the insertion. colOrder <- c(firstHalf, currentPlace, secondHalf) # Putting that order together. } # Reordering the data. data <- subset(data, select = colOrder) # Data Table compatability. if (dClass[1] == "data.table") data <- as.data.table(data) # Returning. return(data) }
J'ai réalisé que je n'incluais pas non plus CheckChoice:
##### # FUNCTION: CheckChoice(names, dataNames, firstWord == "Oops" message = TRUE) # DESCRIPTION: Takes the column names of a data frame and checks to make sure whatever "choice" you made (be it # your choice of dummies or your choice of chops) is actually in the data frame columns. Makes troubleshooting easier. # This function is also important in prechecking names to make sure the formula ends up being right. Use it after # adding in new data to check the "choose" options. Set firstWord to the first word you want said before an exclamation point. # The warn argument (previously message) can be set to TRUE if you only want to ##### CheckChoice <- function(names, dataNames, firstWord = "Oops", warn = FALSE) { for (name in names) { if (warn == TRUE) { if(!(name %in% dataNames)) { warning(paste0(firstWord, "! The column/value/argument, ", name, ", was not valid OR not in your data! Check your input! This is a warning message of that!")) } } if (warn == FALSE) { if(!(name %in% dataNames)) { stop(paste0(firstWord, "! The column/value/argument, " , name, ", was not valid OR not in your data! Check your input!")) } } } }
la source
Solution simple. Dans un bloc de données à 5 colonnes, si vous voulez insérer une autre colonne entre 3 et 4 ...
tmp <- data[, 1:3] tmp$example <- NA # or any value. data <- cbind(tmp, data[, 4:5]
la source
Cette fonction insère une colonne zéro entre toutes les colonnes préexistantes d'un bloc de données.
insertaCols<-function(dad){ nueva<-as.data.frame(matrix(rep(0,nrow(daf)*ncol(daf)*2 ),ncol=ncol(daf)*2)) for(k in 1:ncol(daf)){ nueva[,(k*2)-1]=daf[,k] colnames(nueva)[(k*2)-1]=colnames(daf)[k] } return(nueva) }
la source
Voici un exemple de comment déplacer une colonne de la dernière à la première position. Il se combine
[
avecncol
. J'ai pensé qu'il serait utile d'avoir une réponse très courte ici pour le lecteur occupé:d = mtcars d[, c(ncol(d), 1:(ncol(d)-1))]
la source
Vous pouvez utiliser la
append()
fonction pour insérer des éléments dans des vecteurs ou des listes (les dataframes sont des listes). Simplement:df <- data.frame(a=c(1,2), b=c(3,4), c=c(5,6)) df <- as.data.frame(append(df, list(d=df$b+df$c), after=2))
Ou, si vous souhaitez spécifier la position par nom, utilisez
which
:df <- as.data.frame(append(df, list(d=df$b+df$c), after=which(names(df)=="b")))
la source
»
data1 <- data.frame(col1=1:4, col2=5:8, col3=9:12) row.names(data1) <- c("row1","row2","row3","row4") data1 data2 <- data.frame(col1=21:24, col2=25:28, col3=29:32) row.names(data2) <- c("row1","row2","row3","row4") data2 insertPosition = 2 leftBlock <- unlist(data1[,1:(insertPosition-1)]) insertBlock <- unlist(data2[,1:length(data2[1,])]) rightBlock <- unlist(data1[,insertPosition:length(data1[1,])]) newData <- matrix(c(leftBlock, insertBlock, rightBlock), nrow=length(data1[,1]), byrow=FALSE) newData
»
la source
R n'a pas de fonctionnalité pour spécifier où une nouvelle colonne est ajoutée. Par exemple,
mtcars$mycol<-'foo'
. Il est toujours ajouté comme dernière colonne. En utilisant d'autres moyens (par exempledplyr's select()
), vous pouvez déplacer le mycol vers la position souhaitée. Ce n'est pas idéal et R voudra peut-être essayer de changer cela à l'avenir.la source
append
fonction.Vous pouvez le faire comme ci-dessous -
df <- data.frame(a=1:4, b=5:8, c=9:12) df['d'] <- seq(10,13) df <- df[,c('a','b','d','c')]
la source
df <- data.frame(a=c(1,2), b=c(3,4), c=c(5,6)) df %>% mutate(d= a/2) %>% select(a, b, d, c)
résultats
a b d c 1 1 3 0.5 5 2 2 4 1.0 6
Je suggère d'utiliser
dplyr::select
aprèsdplyr::mutate
. Il dispose de nombreux assistants pour sélectionner / désélectionner un sous-ensemble de colonnes.Dans le contexte de cette question, l'ordre dans lequel vous sélectionnez sera reflété dans la sortie data.frame.
la source
Lorsque vous ne pouvez pas supposer que la colonne
b
vient avant,c
vous pouvez utilisermatch
pour trouver le numéro de colonne des deux,min
pour obtenir le numéro de colonne inférieur etseq_len
pour obtenir une séquence jusqu'à cette colonne. Vous pouvez ensuite utiliser cet index d'abord comme sous-ensemble positif , puis placer la nouvelle colonned
, puis utiliser à nouveau la séquence comme sous-ensemble négatif .i <- seq_len(min(match(c("b", "c"), colnames(x)))) data.frame(x[i], d, x[-i]) #cbind(x[i], d, x[-i]) #Alternative # a b d c #1 1 4 10 7 #2 2 5 11 8 #3 3 6 12 9
Si vous savez que cette colonne
b
précède,c
vous pouvez placer la nouvelle colonned
aprèsb
:i <- seq_len(match("b", colnames(x))) data.frame(x[i], d, x[-i]) # a b d c #1 1 4 10 7 #2 2 5 11 8 #3 3 6 12 9
Les données:
x <- data.frame(a = 1:3, b = 4:6, c = 7:9) d <- 10:12
la source