【发布时间】:2016-11-21 08:46:36
【问题描述】:
我有一个如下所示的 CSV 文件:
a, b, c, d
e, f
我想旋转这些行使其看起来像一个矩阵。一行中的每个项目首先开始,同一行中的所有其他项目在后。
a, b, c, d
b, c, d, a
c, d, a, b
d, a, b, c
e, f
f, e
关于如何在 Java 或 R 中实现这一点的建议?
【问题讨论】:
我有一个如下所示的 CSV 文件:
a, b, c, d
e, f
我想旋转这些行使其看起来像一个矩阵。一行中的每个项目首先开始,同一行中的所有其他项目在后。
a, b, c, d
b, c, d, a
c, d, a, b
d, a, b, c
e, f
f, e
关于如何在 Java 或 R 中实现这一点的建议?
【问题讨论】:
这是第一行使用sapply 和子集的方法:
vec <- letters[1:4]
sapply(1:4, function(i) vec[c(i:4, 1:i)][1:4])
[,1] [,2] [,3] [,4]
[1,] "a" "b" "c" "d"
[2,] "b" "c" "d" "a"
[3,] "c" "d" "a" "b"
[4,] "d" "a" "b" "c"
R 中最简单的方法是使用列表,因为每行中的元素数量不同。使用列表结构,这里有一个嵌套的sapply 方法:
myList <- list(letter[1:4], letters[5:6])
sapply(myList, function(j) {
sapply(1:length(j), function(i) {
j[c(i:length(j), 1:i)][1:length(j)]})})
[[1]]
[,1] [,2] [,3] [,4]
[1,] "a" "b" "c" "d"
[2,] "b" "c" "d" "a"
[3,] "c" "d" "a" "b"
[4,] "d" "a" "b" "c"
[[2]]
[,1] [,2]
[1,] "e" "f"
[2,] "f" "e"
【讨论】:
在R 中,我们可以遍历行并使用matrix 推导出预期的输出
lst <- apply(df, 1, function(x) {x1 <-x[nzchar(x)]
head(matrix(x1, nrow=length(x1)+1, ncol = length(x1)),-1)})
lst
#[[1]]
# [,1] [,2] [,3] [,4]
#[1,] "a" "b" "c" "d"
#[2,] "b" "c" "d" "a"
#[3,] "c" "d" "a" "b"
#[4,] "d" "a" "b" "c"
#[[2]]
# [,1] [,2]
#[1,] "e" "f"
#[2,] "f" "e"
注意:如果我们有 NA 而不是空白 (''),那么上面代码中的 x1 <- x[!is.na(x)]。
如果我们需要创建单个数据集,则可以使用 rbindlist from data.table
library(data.table)
rbindlist(lapply(lst, as.data.frame), fill = TRUE)
# V1 V2 V3 V4
#1: a b c d
#2: b c d a
#3: c d a b
#4: d a b c
#5: e f NA NA
#6: f e NA NA
df <- structure(list(v1 = c("a", "e"), v2 = c("b", "f"), v3 = c("c",
""), v4 = c("d", "")), .Names = c("v1", "v2", "v3", "v4"),
row.names = c(NA, -2L), class = "data.frame")
【讨论】: