Moving Columns Within a Data.Frame() Without Retyping

Moving columns within a data.frame() without retyping

Here is one way to do it:

> col_idx <- grep("g", names(df))
> df <- df[, c(col_idx, (1:ncol(df))[-col_idx])]
> names(df)
[1] "g" "a" "b" "c" "d" "e" "f"

Move a column to first position in a data frame

I don't know if it's worth adding this as an answer or if a comment would be fine, but I wrote a function called moveme that lets you do what you want to do with the language you describe. You can find the function at this answer: https://stackoverflow.com/a/18540144/1270695

It works on the names of your data.frame and produces a character vector that you can use to reorder your columns:

mydf <- data.frame(matrix(1:12, ncol = 4))
mydf
moveme(names(mydf), "X4 first")
# [1] "X4" "X1" "X2" "X3"
moveme(names(mydf), "X4 first; X1 last")
# [1] "X4" "X2" "X3" "X1"

mydf[moveme(names(mydf), "X4 first")]
# X4 X1 X2 X3
# 1 10 1 4 7
# 2 11 2 5 8
# 3 12 3 6 9

If you're shuffling things around like this, I suggest converting your data.frame to a data.table and using setcolorder (with my moveme function, if you wish) to make the change by reference.


In your question, you also mentioned "I just want to pick one column and move it to the start". If it's an arbitrary column, and not specifically the last one, you could also look at using setdiff.

Imagine you're working with the "mtcars" dataset and want to move the "am" column to the start.

x <- "am"
mtcars[c(x, setdiff(names(mtcars), x))]

Move columns by one

Although the answer in comments works for a one-column shift to the right, its fiddly to extend that approach to other shifts and directions.

It boils down to generating the vector of the order of columns that you want to return, and then subsetting columns.

So your original Q boils down to generating c(4,1,2,3). There's a handy function in the magic package that can do this:

> install.packages("magic") # if you dont have it
> magic::shift(1:4,1)
[1] 4 1 2 3

So:

> Data[,magic::shift(1:ncol(Data),1)]
[,1] [,2] [,3] [,4]
[1,] 13 1 5 9
[2,] 14 2 6 10
[3,] 15 3 7 11
[4,] 16 4 8 12

answers your original question. This is then easy to extend to shifts by more than one, or negative (leftward) shifts:

> Data[,magic::shift(1:ncol(Data),-2)]
[,1] [,2] [,3] [,4]
[1,] 9 13 1 5
[2,] 10 14 2 6
[3,] 11 15 3 7
[4,] 12 16 4 8

Of course the right way is now to create matrix shift function:

> mshift = function(m,n=1){m[,magic::shift(1:ncol(m),n)]}

which you can check:

> mshift(Data,1)
[,1] [,2] [,3] [,4]
[1,] 13 1 5 9
[2,] 14 2 6 10
[3,] 15 3 7 11
[4,] 16 4 8 12

R move column to last using dplyr

After some tinkering, the following works and requires very little typing.

data %>% select(-b,b)



UPDATE: dplyr 1.0.0

dplyr 1.0.0 introduces the relocate verb:

data %>% relocate(b, .after = last_col())

I still prefer the old "hacky" way.

Reogranizing the data frame

Try this

tbl_comp <- subset(tbl_comp, select=c(Description , Meve_mean:tot_sdwtm))

Replicate more than one column

I think you need this -

sampled_data <- camp.d[sample(nrow(camp.d), 100, replace = T), ]

head(sampled_data)

Campaignid CampaignName
2 132 b
5 153 e
3 133 c
3.1 133 c
2.1 132 b
4 143 d

Slice data.frame and join back old data.frame without slice

For the sliced sum, you can calculate the sum of rev that is above the 50% quantile as follows; then you can calculate both in the same summarize expression without the need of a join:

df %>% 
group_by(id) %>%
summarise(rev_sliced = sum(rev[rev > quantile(rev, 0.5)]),
rev = sum(rev))

# A tibble: 2 x 3
# id rev_sliced rev
# <int> <dbl> <dbl>
#1 1 225.5171 463.7502
#2 2 209.0919 463.9908


Related Topics



Leave a reply



Submit