是否有使用交替模式重命名列的更简单版本?或者 tidyverse 方法?
Is there a simpler version of renaming columns with alternating patterns? Or tidyverse methods?
我的数据
所以我有一个正在使用的数据框:
structure(list(V1 = c(3L, 3L, 3L, 2L, 4L, 1L), V2 = c(1L, 1L,
1L, 1L, 1L, 1L), V3 = c(2L, 2L, 2L, 1L, 3L, 2L), V4 = c(2L, 2L,
3L, 1L, 1L, 1L), V5 = c(3L, 3L, 4L, 1L, 3L, 3L), V6 = c(3L, 3L,
4L, 3L, 3L, 3L), V7 = c(2L, 2L, 1L, 1L, 3L, 3L), V8 = c(3L, 3L,
4L, 4L, 3L, 3L), V9 = c(3L, 3L, 3L, 2L, 3L, 3L), V10 = c(2L,
2L, 1L, 1L, 1L, 1L)), row.names = c(NA, 6L), class = "data.frame")
看起来像这样:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
目前的解决方案
我想出的用于快速重命名变量的最佳代码是:
new_names <- outer("cope",
1:10,
paste,
sep="_")
names(data1) <- new_names
data1
这给了我这个数据框:
cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
问题
虽然这足以满足我的目的,但它让我考虑了未来的两个问题。首先,有没有办法简化代码以使其成为一行?如果可能的话,我正在考虑在 dplyr 中工作的东西,因为这是我最习惯使用的东西。
其次,如果有 30 个变量,我预见到即将出现的问题,其中一些变量具有重复模式,而另一些变量是唯一的。像这样重命名变量时最经济的时间使用是什么?我知道 rep
是一种选择,但我只知道它如何重复而不是将值分成多个模式。我在想这样的事情,用某种模式和停止来写会更容易:
names <- c("v1","v2","v3","c1","c2","c3","u","p","z1","z2")
例如:
names <- c("v1","v2","v3","c1","c2","c3","u","p","z1","z2")
colnames(data1) <- names
data1
v1 v2 v3 c1 c2 c3 u p z1 z2
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
7 3 1 3 1 3 2 2 2 3 2
8 3 2 1 2 3 2 3 3 2 1
9 3 2 4 1 2 4 2 3 4 1
10 4 2 4 2 3 4 3 3 4 1
手动拼写很费时间:
names <- c("cope_1", "cope_2","cope_3","sad_1","sad_2","sad_3","u","p","zip_1","zip_2")
colnames(data1) <- names
data1
哪个确实能让你得到你想要的,但速度很慢:
cope_1 cope_2 cope_3 sad_1 sad_2 sad_3 u p zip_1 zip_2
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
outer
之类的东西似乎不适合这里:
outer("cope",
1:3,
paste,
sep="_",
"sad",
1:3,
paste,
sep="_",
"u",
"p")
因此,如果有更好的方法来命名像这样的变量块,那将是一件很棒的事情。
一个解决方案可能是这样的:
library(dplyr)
df %>%
setNames(paste0("cope_", seq_len(ncol(df))))
cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
如果你有一个包含名称的向量 x
和一个包含重复次数的向量 r
,那么你可以这样做:
x <- c("v", "c", "u", "p", "z")
r <- c(3L, 3L, 1L, 1L, 3L)
f <- function(n) if (n > 1L) seq_len(n) else character(n)
paste0(rep(x, r), unlist(lapply(r, f)))
## [1] "v1" "v2" "v3" "c1" "c2" "c3" "u" "p" "z1" "z2" "z3"
如果你对"u1"
和"p1"
没问题,那么你可以简化一点:
paste0(rep(x, r), unlist(lapply(r, seq_len)))
## [1] "v1" "v2" "v3" "c1" "c2" "c3" "u1" "p1" "z1" "z2" "z3"
还有基数 R make.unique
。它更识字,但笨拙地只有数字重复,所以它并不能完全满足你的需求:
make.unique(rep(x, r), sep = "")
## [1] "v" "v1" "v2" "c" "c1" "c2" "u" "p" "z" "z1" "z2"
您可以在 dplyr
-
中使用 rename_with
library(dplyr)
df %>% rename_with(~paste0('cope_', seq_along(.)))
# cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
#1 3 1 2 2 3 3 2 3 3 2
#2 3 1 2 2 3 3 2 3 3 2
#3 3 1 2 3 4 4 1 4 3 1
#4 2 1 1 1 1 3 1 4 2 1
#5 4 1 3 1 3 3 3 3 3 1
#6 1 1 2 1 3 3 3 3 3 1
我的数据
所以我有一个正在使用的数据框:
structure(list(V1 = c(3L, 3L, 3L, 2L, 4L, 1L), V2 = c(1L, 1L,
1L, 1L, 1L, 1L), V3 = c(2L, 2L, 2L, 1L, 3L, 2L), V4 = c(2L, 2L,
3L, 1L, 1L, 1L), V5 = c(3L, 3L, 4L, 1L, 3L, 3L), V6 = c(3L, 3L,
4L, 3L, 3L, 3L), V7 = c(2L, 2L, 1L, 1L, 3L, 3L), V8 = c(3L, 3L,
4L, 4L, 3L, 3L), V9 = c(3L, 3L, 3L, 2L, 3L, 3L), V10 = c(2L,
2L, 1L, 1L, 1L, 1L)), row.names = c(NA, 6L), class = "data.frame")
看起来像这样:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
目前的解决方案
我想出的用于快速重命名变量的最佳代码是:
new_names <- outer("cope",
1:10,
paste,
sep="_")
names(data1) <- new_names
data1
这给了我这个数据框:
cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
问题
虽然这足以满足我的目的,但它让我考虑了未来的两个问题。首先,有没有办法简化代码以使其成为一行?如果可能的话,我正在考虑在 dplyr 中工作的东西,因为这是我最习惯使用的东西。
其次,如果有 30 个变量,我预见到即将出现的问题,其中一些变量具有重复模式,而另一些变量是唯一的。像这样重命名变量时最经济的时间使用是什么?我知道 rep
是一种选择,但我只知道它如何重复而不是将值分成多个模式。我在想这样的事情,用某种模式和停止来写会更容易:
names <- c("v1","v2","v3","c1","c2","c3","u","p","z1","z2")
例如:
names <- c("v1","v2","v3","c1","c2","c3","u","p","z1","z2")
colnames(data1) <- names
data1
v1 v2 v3 c1 c2 c3 u p z1 z2
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
7 3 1 3 1 3 2 2 2 3 2
8 3 2 1 2 3 2 3 3 2 1
9 3 2 4 1 2 4 2 3 4 1
10 4 2 4 2 3 4 3 3 4 1
手动拼写很费时间:
names <- c("cope_1", "cope_2","cope_3","sad_1","sad_2","sad_3","u","p","zip_1","zip_2")
colnames(data1) <- names
data1
哪个确实能让你得到你想要的,但速度很慢:
cope_1 cope_2 cope_3 sad_1 sad_2 sad_3 u p zip_1 zip_2
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
outer
之类的东西似乎不适合这里:
outer("cope",
1:3,
paste,
sep="_",
"sad",
1:3,
paste,
sep="_",
"u",
"p")
因此,如果有更好的方法来命名像这样的变量块,那将是一件很棒的事情。
一个解决方案可能是这样的:
library(dplyr)
df %>%
setNames(paste0("cope_", seq_len(ncol(df))))
cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
1 3 1 2 2 3 3 2 3 3 2
2 3 1 2 2 3 3 2 3 3 2
3 3 1 2 3 4 4 1 4 3 1
4 2 1 1 1 1 3 1 4 2 1
5 4 1 3 1 3 3 3 3 3 1
6 1 1 2 1 3 3 3 3 3 1
如果你有一个包含名称的向量 x
和一个包含重复次数的向量 r
,那么你可以这样做:
x <- c("v", "c", "u", "p", "z")
r <- c(3L, 3L, 1L, 1L, 3L)
f <- function(n) if (n > 1L) seq_len(n) else character(n)
paste0(rep(x, r), unlist(lapply(r, f)))
## [1] "v1" "v2" "v3" "c1" "c2" "c3" "u" "p" "z1" "z2" "z3"
如果你对"u1"
和"p1"
没问题,那么你可以简化一点:
paste0(rep(x, r), unlist(lapply(r, seq_len)))
## [1] "v1" "v2" "v3" "c1" "c2" "c3" "u1" "p1" "z1" "z2" "z3"
还有基数 R make.unique
。它更识字,但笨拙地只有数字重复,所以它并不能完全满足你的需求:
make.unique(rep(x, r), sep = "")
## [1] "v" "v1" "v2" "c" "c1" "c2" "u" "p" "z" "z1" "z2"
您可以在 dplyr
-
rename_with
library(dplyr)
df %>% rename_with(~paste0('cope_', seq_along(.)))
# cope_1 cope_2 cope_3 cope_4 cope_5 cope_6 cope_7 cope_8 cope_9 cope_10
#1 3 1 2 2 3 3 2 3 3 2
#2 3 1 2 2 3 3 2 3 3 2
#3 3 1 2 3 4 4 1 4 3 1
#4 2 1 1 1 1 3 1 4 2 1
#5 4 1 3 1 3 3 3 3 3 1
#6 1 1 2 1 3 3 3 3 3 1