Saya menghapus nama-menjatuhkan. Tampaknya tidak menambahkan banyak, dan sementara Hadley terdaftar sebagai seorang penulis paket Kirill Müller terdaftar sebagai pencipta dan pemelihara .
Saya menemukan pengurutan ulang yang digunakan setcolorderdalam hubungannya dengan nomor kolom (sebagai lawan dari namanya) juga sangat berguna, karena begitu jumlah kolom menjadi sangat besar, Anda dapat mulai menggunakan seqdan repmelakukan sebagian besar pekerjaan. Ditambah operator aritmatika dapat digunakan. Misalnyasetcolorder(data, c(1, (num_cols -2), (num_cols -1), num_cols, seq(from = 2, to = (num_cols - 3))))
n1k31t4
1
Saya harus menyebutkan, setcolorderini dimaksudkan untuk data.table, bukan data.frame!
n1k31t4
21
Anda dapat menyusun ulang kolom dengan [, atau menyajikan kolom dalam urutan yang Anda inginkan.
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 c115129226131033714114481512
Ini jawaban yang bagus. Tapi harus saya akui, ini juga contoh yang bagus mengapa R bisa jadi sulit bagi pemula.
tumultous_rooster
2
Karena itu, menurut saya @ ashah57 memiliki jawaban yang lebih sederhana dan lebih bersih di bawah ini. Tidak perlu terlalu memikirkan hal seperti ini.
tumultous_rooster
12
Menganggap bahwa cselalu segera mengikuti b, kode ini akan menambahkan kolom setelah di bmana bpun di data.frame Anda.
> test <- data.frame(a=1,b=1,c=1)
> test
a b c1111
> bspot <- which(names(test)=="b")
> data.frame(test[1:bspot],d=2,test[(bspot+1):ncol(test)])
a b d c11121
Berikut cara cepat dan kotor memasukkan kolom di posisi tertentu pada bingkai data. Dalam kasus saya, saya memiliki 5 kolom dalam bingkai data asli: c1, c2, c3, c4, c5dan saya akan menyisipkan kolom baru c2bantara c2dan c3.
1) Pertama-tama, mari buat bingkai data pengujian:
3) Susun ulang bingkai data berdasarkan indeks kolom. Dalam kasus saya, saya ingin menyisipkan kolom baru (6) antara kolom 2 dan 3. Saya melakukannya dengan menangani kolom pada bingkai data saya menggunakan vektor c(1:2, 6, 3:5)yang setara dengan c(1, 2, 6, 3, 4, 5).
Untuk apa nilainya, saya menulis fungsi untuk melakukan ini:
[dihapus]
Saya sekarang telah memperbarui fungsi ini dengan beforedan afterfungsi dan default placeke 1. Ini juga memiliki tabel data kompatibilitas:
###### 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)
}
Saya menyadari bahwa saya juga tidak menyertakan 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 innames) {
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!")) } }
}
}
Berikut adalah contoh cara memindahkan kolom dari posisi terakhir ke posisi pertama. Ini digabungkan [dengan ncol. Saya pikir akan bermanfaat untuk memiliki jawaban yang sangat singkat di sini untuk pembaca yang sibuk:
R tidak memiliki fungsionalitas untuk menentukan di mana kolom baru ditambahkan. Misalnya mtcars$mycol<-'foo',. Itu selalu ditambahkan sebagai kolom terakhir. Menggunakan cara lain (misalnya dplyr's select()) Anda dapat memindahkan mycol ke posisi yang diinginkan. Ini tidak ideal dan R mungkin ingin mencoba mengubahnya di masa depan.
Ketika Anda tidak dapat berasumsi bahwa kolom bdatang sebelum cAnda dapat menggunakan matchuntuk menemukan nomor kolom keduanya, minuntuk mendapatkan nomor kolom yang lebih rendah dan seq_lenuntuk mendapatkan urutan sampai kolom ini. Kemudian Anda dapat menggunakan indeks ini terlebih dahulu sebagai subset positif , kemudian menempatkan kolom baru ddan kemudian menggunakan urutannya lagi sebagai subset negatif .
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
Jika Anda tahu bahwa kolom bmuncul sebelum cAnda dapat menempatkan kolom baru dsetelah 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
Data:
x <- data.frame(a = 1:3, b = 4:6, c = 7:9)
d <- 10:12
Jawaban:
Saya menyarankan Anda untuk menggunakan fungsi
add_column()
daritibble
paket.library(tibble) dataset <- data.frame(a = 1:5, b = 2:6, c=3:7) add_column(dataset, d = 4:8, .after = 2)
Perhatikan bahwa Anda bisa menggunakan nama kolom dan bukan indeks kolom:
add_column(dataset, d = 4:8, .after = "b")
Atau gunakan argumen
.before
daripada.after
jika lebih nyaman.add_column(dataset, d = 4:8, .before = "c")
sumber
Tambahkan di kolom baru Anda:
df$d <- list/data
Kemudian Anda dapat menyusunnya kembali.
df <- df[, c("a", "b", "d", "c")]
sumber
setcolorder
dalam hubungannya dengan nomor kolom (sebagai lawan dari namanya) juga sangat berguna, karena begitu jumlah kolom menjadi sangat besar, Anda dapat mulai menggunakanseq
danrep
melakukan sebagian besar pekerjaan. Ditambah operator aritmatika dapat digunakan. Misalnyasetcolorder(data, c(1, (num_cols -2), (num_cols -1), num_cols, seq(from = 2, to = (num_cols - 3))))
setcolorder
ini dimaksudkan untuk data.table, bukan data.frame!Anda dapat menyusun ulang kolom dengan [, atau menyajikan kolom dalam urutan yang Anda inginkan.
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
sumber
Menganggap bahwa
c
selalu segera mengikutib
, kode ini akan menambahkan kolom setelah dib
manab
pun di data.frame Anda.> 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
Atau mungkin lebih alami:
data.frame(append(test, list(d=2), after=match("b", names(test))))
sumber
Buat contoh data.frame dan tambahkan kolom ke dalamnya.
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
Susun ulang menurut indeks kolom
df[, colnames(df)[c(1:2,4,3)]]
atau dengan nama kolom
df[, c('a', 'b', 'd', 'c')]
Hasilnya adalah
a b d c 1 1 4 10 7 2 2 5 11 8 3 3 6 12 9
sumber
Anda ingin menambahkan kolom z ke bingkai data lama (old.df) yang ditentukan oleh kolom x dan y.
z = rbinom(1000, 5, 0.25) old.df <- data.frame(x = c(1:1000), y = rnorm(1:1000)) head(old.df)
Tentukan bingkai data baru yang disebut new.df
new.df <- data.frame(x = old.df[,1], z, y = old.df[,2]) head(new.df)
sumber
Berikut cara cepat dan kotor memasukkan kolom di posisi tertentu pada bingkai data. Dalam kasus saya, saya memiliki 5 kolom dalam bingkai data asli:
c1, c2, c3, c4, c5
dan saya akan menyisipkan kolom baruc2b
antarac2
danc3
.1) Pertama-tama, mari buat bingkai data pengujian:
> 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) Tambahkan kolom baru
c2b
di akhir bingkai data kami:> 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) Susun ulang bingkai data berdasarkan indeks kolom. Dalam kasus saya, saya ingin menyisipkan kolom baru (6) antara kolom 2 dan 3. Saya melakukannya dengan menangani kolom pada bingkai data saya menggunakan vektor
c(1:2, 6, 3:5)
yang setara denganc(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
Sana!
sumber
Untuk apa nilainya, saya menulis fungsi untuk melakukan ini:
[dihapus]
Saya sekarang telah memperbarui fungsi ini dengan
before
danafter
fungsi dan defaultplace
ke 1. Ini juga memiliki tabel data kompatibilitas:##### # 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) }
Saya menyadari bahwa saya juga tidak menyertakan 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!")) } } } }
sumber
Solusi mudah. Dalam bingkai data dengan 5 kolom, Jika Anda ingin memasukkan kolom lain antara 3 dan 4 ...
tmp <- data[, 1:3] tmp$example <- NA # or any value. data <- cbind(tmp, data[, 4:5]
sumber
Fungsi ini menyisipkan satu kolom nol di antara semua kolom yang sudah ada sebelumnya dalam bingkai data.
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) }
sumber
Berikut adalah contoh cara memindahkan kolom dari posisi terakhir ke posisi pertama. Ini digabungkan
[
denganncol
. Saya pikir akan bermanfaat untuk memiliki jawaban yang sangat singkat di sini untuk pembaca yang sibuk:d = mtcars d[, c(ncol(d), 1:(ncol(d)-1))]
sumber
Anda dapat menggunakan
append()
fungsi untuk memasukkan item ke dalam vektor atau daftar (bingkai data adalah daftar). Secara sederhana: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))
Atau, jika Anda ingin menentukan posisi berdasarkan nama, gunakan
which
:df <- as.data.frame(append(df, list(d=df$b+df$c), after=which(names(df)=="b")))
sumber
`
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
`
sumber
R tidak memiliki fungsionalitas untuk menentukan di mana kolom baru ditambahkan. Misalnya
mtcars$mycol<-'foo'
,. Itu selalu ditambahkan sebagai kolom terakhir. Menggunakan cara lain (misalnyadplyr's select()
) Anda dapat memindahkan mycol ke posisi yang diinginkan. Ini tidak ideal dan R mungkin ingin mencoba mengubahnya di masa depan.sumber
append
fungsinya.Anda dapat melakukannya seperti di bawah ini -
df <- data.frame(a=1:4, b=5:8, c=9:12) df['d'] <- seq(10,13) df <- df[,c('a','b','d','c')]
sumber
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)
hasil
a b d c 1 1 3 0.5 5 2 2 4 1.0 6
Saya sarankan untuk digunakan
dplyr::select
setelahdplyr::mutate
. Ini memiliki banyak pembantu untuk memilih / membatalkan pilihan subset kolom.Dalam konteks pertanyaan ini, urutan yang Anda pilih akan tercermin dalam output data.frame.
sumber
Ketika Anda tidak dapat berasumsi bahwa kolom
b
datang sebelumc
Anda dapat menggunakanmatch
untuk menemukan nomor kolom keduanya,min
untuk mendapatkan nomor kolom yang lebih rendah danseq_len
untuk mendapatkan urutan sampai kolom ini. Kemudian Anda dapat menggunakan indeks ini terlebih dahulu sebagai subset positif , kemudian menempatkan kolom barud
dan kemudian menggunakan urutannya lagi sebagai subset negatif .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
Jika Anda tahu bahwa kolom
b
muncul sebelumc
Anda dapat menempatkan kolom barud
setelahb
: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
Data:
x <- data.frame(a = 1:3, b = 4:6, c = 7:9) d <- 10:12
sumber