这个问题是How to append column number in front of every element?
的后续行动V1 <- c("a", "a", "b", "b", "b")
V2 <- c("c" ,"d", "e" ,"e", "f")
V3 <- c("i", "j", "k", "l", "m")
df <- data.frame(V1, V2, V3)
df[] <- Map(paste0, seq_along(df), df)
输出
V1 V2 V3
1 1a 2c 3i
2 1a 2d 3j
3 1b 2e 3k
4 1b 2e 3l
5 1b 2f 3m
我该如何创建以下输出?
V1 V2 V3
1 1.1.a 2.1.c 3.1.i
2 1.1.a 2.2.d 3.2.j
3 1.2.b 2.3.e 3.3.k
4 1.2.b 2.3.e 3.4.l
5 1.2.b 2.4.f 3.5.m
答案 0 :(得分:3)
V1 <- c("a", "a", "b", "b", "b")
V2 <- c("c" ,"d", "e" ,"e", "f")
V3 <- c("i", "j", "k", "l", "m")
dtf <- data.frame(V1, V2, V3)
num <- sapply(dtf, function(x) cumsum(-duplicated(x) + 1))
(m <- sapply(1:3, function(x) paste(x, num[, x], dtf[, x], sep=".")))
# [,1] [,2] [,3]
# [1,] "1.1.a" "2.1.c" "3.1.i"
# [2,] "1.1.a" "2.2.d" "3.2.j"
# [3,] "1.2.b" "2.3.e" "3.3.k"
# [4,] "1.2.b" "2.3.e" "3.4.l"
# [5,] "1.2.b" "2.4.f" "3.5.m"
这是一个没有列名的矩阵,但是我们可以解决这个问题。
as.data.frame(m, col.names=colnames(dtf))
# V1 V2 V3
# 1 1.1.a 2.1.c 3.1.i
# 2 1.1.a 2.2.d 3.2.j
# 3 1.2.b 2.3.e 3.3.k
# 4 1.2.b 2.3.e 3.4.l
# 5 1.2.b 2.4.f 3.5.m
答案 1 :(得分:3)
您可以使用Map
之前的lapply
指令。
f <- function(x){
sp <- split(x, x)
unlist(lapply(seq_along(sp), function(i) paste(i, sp[[i]], sep = ".")))
}
df[] <- lapply(df, f)
df[] <- Map(paste, seq_along(df), df, sep = ".")
df
# V1 V2 V3
#1 1.1.a 2.1.c 3.1.i
#2 1.1.a 2.2.d 3.2.j
#3 1.2.b 2.3.e 3.3.k
#4 1.2.b 2.3.e 3.4.l
#5 1.2.b 2.4.f 3.5.m
答案 2 :(得分:2)
另一种选择是将match
与每一列的unique
元素一起使用,并执行paste
df[] <- paste(col(df), sapply(df, function(x) match(x, unique(x))),
as.matrix(df), sep=".")
df
# V1 V2 V3
#1 1.1.a 2.1.c 3.1.i
#2 1.1.a 2.2.d 3.2.j
#3 1.2.b 2.3.e 3.3.k
#4 1.2.b 2.3.e 3.4.l
#5 1.2.b 2.4.f 3.5.m
或使用tidyverse
library(tidyverse)
imap(seq_along(df), ~
df %>%
select(.x) %>%
mutate_at(1, funs(paste(.y, match(., unique(.)), ., sep="." )))) %>%
bind_cols
# V1 V2 V3
#1 1.1.a 2.1.c 3.1.i
#2 1.1.a 2.2.d 3.2.j
#3 1.2.b 2.3.e 3.3.k
#4 1.2.b 2.3.e 3.4.l
#5 1.2.b 2.4.f 3.5.m