在 R 中将多行粘贴在一起
Paste multiple rows together in R
我有一个数据框,我想得到矩阵,第 1 行粘贴到第 2 行,第 3 行粘贴到第 4 行,如果数据框有奇数行,则保留最后一行,而不是粘贴行,粘贴第 1 列和第 2 列,第 3 列和第 4 列,矩阵将为:
data <- data.frame(name = c(1:4), plate=c("A","B","C","D"), value1=c(4:7), value2 = c(100, 200, 300, 400))
data
name plate value1 value2
1 A 4 100
2 B 5 200
3 C 6 300
4 D 7 400
矩阵按行粘贴的结果:
name plate value1 value2
1-2 A-B 4-5 100-200
3-4 C-D 6-7 300-400
矩阵按列粘贴的结果:
name-plate value1-value2
1-A 4-100
2-B 5-200
3-C 6-300
4-D 7-400
我知道怎么把它们全部贴在一起,但我不知道怎么分开
> apply( data[,1:4] , 1, paste , collapse = "-" )
[1] "1-A-4-100" "2-B-5-200" "3-C-6-300" "4-D-7-400"
感谢您的帮助。
您可能可以从类似下面的内容开始,在其中分别提取奇数 (data[c(T, F), ])
和偶数 (data[c(F, T), ])
行,然后使用 mapply
函数同时循环并粘贴他们在一起。列也有类似的逻辑。
mapply(paste, sep = "-", data[c(T,F),], data[c(F,T),])
# - <NA> <NA> <NA>
# [1,] "1-2" "A-B" "4-5" "100-200"
# [2,] "3-4" "C-D" "6-7" "300-400"
mapply(paste, sep = "-", dat[,c(T,F)], dat[,c(F,T)])
# - <NA>
# [1,] "1-A" "4-100"
# [2,] "2-B" "5-200"
# [3,] "3-C" "6-300"
如果需要同时设置列名:
setNames(as.data.frame(mapply(paste, sep = "-", data[c(T,F),], data[c(F,T),])),
names(data))
# name plate value1 value2
# 1 1-2 A-B 4-5 100-200
# 2 3-4 C-D 6-7 300-400
setNames(as.data.frame(mapply(paste, sep = "-", data[,c(T,F)], data[,c(F,T)])),
paste(names(data)[c(T,F)], names(data)[c(F,T)], sep = "-"))
# name-plate value1-value2
# 1 1-A 4-100
# 2 2-B 5-200
# 3 3-C 6-300
# 4 4-D 7-400
注意:这不会处理奇数行或奇数列的情况,因此您需要一些努力来处理它。
我们可以用 lapply
as.data.frame(t(sapply(seq(1, nrow(data), by = 2), function(i)
apply(data[i:(i+1),], 2, paste, collapse="-"))))
# name plate value1 value2
#1 1-2 A-B 4-5 100-200
#2 3-4 C-D 6-7 300-400
setNames(as.data.frame(sapply(seq(1, nrow(data), by = 2), function(i)
apply(data[,i:(i+1)], 1, paste, collapse="-"))), c("name-plate", "value1-value2"))
# name-plate value1-value2
#1 1-A 4-100
#2 2-B 5-200
#3 3-C 6-300
#4 4-D 7-400
另一种方法是使用 tidyr 包中的联合函数。
library(tidyr)
data <- data.frame(name = c(1:4),
plate=c("A","B","C","D"),
value1=c(4:7),
value2 = c(100, 200, 300, 400))
data %>%
unite("name-plate", name, plate, remove = T, sep = "-") %>%
unite("value1-value2", value1, value2, remove = T, sep = "-")
# outputs the following data.frame
name-plate value1-value2
1 1-A 4-100
2 2-B 5-200
3 3-C 6-300
4 4-D 7-400
我有一个数据框,我想得到矩阵,第 1 行粘贴到第 2 行,第 3 行粘贴到第 4 行,如果数据框有奇数行,则保留最后一行,而不是粘贴行,粘贴第 1 列和第 2 列,第 3 列和第 4 列,矩阵将为:
data <- data.frame(name = c(1:4), plate=c("A","B","C","D"), value1=c(4:7), value2 = c(100, 200, 300, 400))
data
name plate value1 value2
1 A 4 100
2 B 5 200
3 C 6 300
4 D 7 400
矩阵按行粘贴的结果:
name plate value1 value2
1-2 A-B 4-5 100-200
3-4 C-D 6-7 300-400
矩阵按列粘贴的结果:
name-plate value1-value2
1-A 4-100
2-B 5-200
3-C 6-300
4-D 7-400
我知道怎么把它们全部贴在一起,但我不知道怎么分开
> apply( data[,1:4] , 1, paste , collapse = "-" )
[1] "1-A-4-100" "2-B-5-200" "3-C-6-300" "4-D-7-400"
感谢您的帮助。
您可能可以从类似下面的内容开始,在其中分别提取奇数 (data[c(T, F), ])
和偶数 (data[c(F, T), ])
行,然后使用 mapply
函数同时循环并粘贴他们在一起。列也有类似的逻辑。
mapply(paste, sep = "-", data[c(T,F),], data[c(F,T),])
# - <NA> <NA> <NA>
# [1,] "1-2" "A-B" "4-5" "100-200"
# [2,] "3-4" "C-D" "6-7" "300-400"
mapply(paste, sep = "-", dat[,c(T,F)], dat[,c(F,T)])
# - <NA>
# [1,] "1-A" "4-100"
# [2,] "2-B" "5-200"
# [3,] "3-C" "6-300"
如果需要同时设置列名:
setNames(as.data.frame(mapply(paste, sep = "-", data[c(T,F),], data[c(F,T),])),
names(data))
# name plate value1 value2
# 1 1-2 A-B 4-5 100-200
# 2 3-4 C-D 6-7 300-400
setNames(as.data.frame(mapply(paste, sep = "-", data[,c(T,F)], data[,c(F,T)])),
paste(names(data)[c(T,F)], names(data)[c(F,T)], sep = "-"))
# name-plate value1-value2
# 1 1-A 4-100
# 2 2-B 5-200
# 3 3-C 6-300
# 4 4-D 7-400
注意:这不会处理奇数行或奇数列的情况,因此您需要一些努力来处理它。
我们可以用 lapply
as.data.frame(t(sapply(seq(1, nrow(data), by = 2), function(i)
apply(data[i:(i+1),], 2, paste, collapse="-"))))
# name plate value1 value2
#1 1-2 A-B 4-5 100-200
#2 3-4 C-D 6-7 300-400
setNames(as.data.frame(sapply(seq(1, nrow(data), by = 2), function(i)
apply(data[,i:(i+1)], 1, paste, collapse="-"))), c("name-plate", "value1-value2"))
# name-plate value1-value2
#1 1-A 4-100
#2 2-B 5-200
#3 3-C 6-300
#4 4-D 7-400
另一种方法是使用 tidyr 包中的联合函数。
library(tidyr)
data <- data.frame(name = c(1:4),
plate=c("A","B","C","D"),
value1=c(4:7),
value2 = c(100, 200, 300, 400))
data %>%
unite("name-plate", name, plate, remove = T, sep = "-") %>%
unite("value1-value2", value1, value2, remove = T, sep = "-")
# outputs the following data.frame
name-plate value1-value2
1 1-A 4-100
2 2-B 5-200
3 3-C 6-300
4 4-D 7-400