R - 从长到宽重塑,按两个变量分组
R - Reshape long to wide, grouping by two variables
我有一个名为 result
的数据框,它有 4 列(x、y、标签、NN.idx 和 dist),分别代表观察点在平面中的位置,一个用于避免(x ,y) 复制(见下面我的评论)它在另一个数据帧中最近邻居的索引和到它的距离。
备注:每个 (x,y) 组合可能出现一到三次,如果出现,则用不同的标签区分它们(例如第 1,4 和 5 行以及下例)。另外,请注意两个不同的点可能具有相同的标签,这是我根据之前的数据操作计算出的数量,例如第 1 行和第 3 行具有相同的标签,但它们显然不代表相同的点 (x,y)。
这是一个例子:
result <- data.frame(x=c(0.147674, 0.235356 ,0.095337, 0.147674, 0.147674, 1.000000, 2.000000), y=c(0.132956, 0.150813, 0.087345, 0.132956, 0.132956, 2.000000, 1.000000), label = c(5,6,5,6,7,3,9), NN.idx =c(4325,2703,21282,3460,12,4,10), dist=c(0.02391247,0.03171236,0.01760940,0.03136304, 0.02315468, 0.01567365, 0.02314860))
head(result)
x y label NN.idx dist
1 0.147674 0.132956 5 4325 0.02391247
2 0.235356 0.150813 6 2703 0.03171236
3 0.095337 0.087345 5 21282 0.01760940
4 0.147674 0.132956 6 3460 0.03136304
5 0.147674 0.132956 7 12 0.02315468
6 1.000000 2.000000 3 4 5.00000000
7 2.000000 1.000000 9 10 11.00000000
我想做的是非常有效地将这个数据框(实际数据框要大得多)重塑为宽格式,其中每一行对应一个 unique (x, y) 组合并显示列 NN.idx_1, NN.idx_2, NN.idx_3, dist_1, dist_2, dist_3 给出 NN.idx 和 dist 对于原始数据框中每次出现的 (x,y) 组合(如果 (x,y) 组合只出现两次或一次,则用 NA 填充)
我对 R 比较陌生,只知道基础知识,但我想我可能有一个使用 data.table
和 dcast
的解决方案,如下所示:
df <- setDT(result)
df[,NN.counter := 1:.N, by=c("x","y")]
df <- dcast(df, x+y~ NN.counter, value.var=c("NN.idx","dist"))
head(df)
x y NN.idx_1 NN.idx_2 NN.idx_3 dist_1 dist_2 dist_3
1: 0.095337 0.087345 21282 NA NA 0.01760940 NA NA
2: 0.147674 0.132956 4325 3460 12 0.02391247 0.03136304 0.02315468
3: 0.235356 0.150813 2703 NA NA 0.03171236 NA NA
4: 1.000000 2.000000 4 NA NA 0.01567365 NA NA
5: 2.000000 1.000000 10 NA NA 0.02314860 NA NA
我的问题是:我的方法可以吗?我不熟悉 dcast
并且符号 x+y ~ NN.counter
让我想知道是否两个不同的点 (x,y) 导致相同的和 x+y 会被认为是不同的(例如第 6 行和第 7 行我的原始数据框,其中 x 和 y 颠倒了)。显然它似乎有效。
有没有人有更好的方法来处理这个重复的问题,或者我的可以吗?另外,我不知道这是否相当快,尽管我读过 data.table
非常快。
由于 x
和 y
都是 numeric
,您可能 运行 遇到基于浮点精度的问题(即 R FAQ 7.31 and IEEE-754) .虽然它可能有效,但我不知道我会严格依赖它(没有大量验证)。在分组和 dcast
ing.
之前强制转换为固定长度的字符串(例如 sprintf("%0.06f", x)
)可能很有用(出于重塑的目的)
这里有一个想法可以解决这个问题。 (注意:我使用 magrittr
只是为了用 %>%
管道分解步骤,它不需要运行。)
library(data.table)
library(magrittr)
result <- data.table(x=c(0.147674, 0.235356 ,0.095337, 0.147674, 0.147674, 1.000000, 2.000000), y=c(0.132956, 0.150813, 0.087345, 0.132956, 0.132956, 2.000000, 1.000000), label = c(5,6,5,6,7,3,9), NN.idx =c(4325,2703,21282,3460,12,4,10), dist=c(0.02391247,0.03171236,0.01760940,0.03136304, 0.02315468, 0.01567365, 0.02314860))
result[, c("x_s", "y_s") := lapply(.(x, y), sprintf, fmt = "%0.09f") ]
savexy <- unique(result[, .(x, y, x_s, y_s) ]) # merge back in later with "real" numbers
result2 <- copy(result) %>%
.[, c("x", "y") := NULL ] %>%
.[, NN.counter := seq_len(.N), by = c("x_s", "y_s") ] %>%
dcast(x_s + y_s ~ NN.counter, value.var = c("NN.idx", "dist") ) %>%
merge(., savexy, by = c("x_s", "y_s"), all.x = TRUE) %>%
.[, c("x_s", "y_s") := NULL ] %>%
setcolorder(., c("x", "y"))
result2
# x y NN.idx_1 NN.idx_2 NN.idx_3 dist_1 dist_2 dist_3
# 1: 0.095337 0.087345 21282 NA NA 0.01760940 NA NA
# 2: 0.147674 0.132956 4325 3460 12 0.02391247 0.03136304 0.02315468
# 3: 0.235356 0.150813 2703 NA NA 0.03171236 NA NA
# 4: 1.000000 2.000000 4 NA NA 0.01567365 NA NA
# 5: 2.000000 1.000000 10 NA NA 0.02314860 NA NA
我有一个名为 result
的数据框,它有 4 列(x、y、标签、NN.idx 和 dist),分别代表观察点在平面中的位置,一个用于避免(x ,y) 复制(见下面我的评论)它在另一个数据帧中最近邻居的索引和到它的距离。
备注:每个 (x,y) 组合可能出现一到三次,如果出现,则用不同的标签区分它们(例如第 1,4 和 5 行以及下例)。另外,请注意两个不同的点可能具有相同的标签,这是我根据之前的数据操作计算出的数量,例如第 1 行和第 3 行具有相同的标签,但它们显然不代表相同的点 (x,y)。
这是一个例子:
result <- data.frame(x=c(0.147674, 0.235356 ,0.095337, 0.147674, 0.147674, 1.000000, 2.000000), y=c(0.132956, 0.150813, 0.087345, 0.132956, 0.132956, 2.000000, 1.000000), label = c(5,6,5,6,7,3,9), NN.idx =c(4325,2703,21282,3460,12,4,10), dist=c(0.02391247,0.03171236,0.01760940,0.03136304, 0.02315468, 0.01567365, 0.02314860))
head(result)
x y label NN.idx dist
1 0.147674 0.132956 5 4325 0.02391247
2 0.235356 0.150813 6 2703 0.03171236
3 0.095337 0.087345 5 21282 0.01760940
4 0.147674 0.132956 6 3460 0.03136304
5 0.147674 0.132956 7 12 0.02315468
6 1.000000 2.000000 3 4 5.00000000
7 2.000000 1.000000 9 10 11.00000000
我想做的是非常有效地将这个数据框(实际数据框要大得多)重塑为宽格式,其中每一行对应一个 unique (x, y) 组合并显示列 NN.idx_1, NN.idx_2, NN.idx_3, dist_1, dist_2, dist_3 给出 NN.idx 和 dist 对于原始数据框中每次出现的 (x,y) 组合(如果 (x,y) 组合只出现两次或一次,则用 NA 填充)
我对 R 比较陌生,只知道基础知识,但我想我可能有一个使用 data.table
和 dcast
的解决方案,如下所示:
df <- setDT(result)
df[,NN.counter := 1:.N, by=c("x","y")]
df <- dcast(df, x+y~ NN.counter, value.var=c("NN.idx","dist"))
head(df)
x y NN.idx_1 NN.idx_2 NN.idx_3 dist_1 dist_2 dist_3
1: 0.095337 0.087345 21282 NA NA 0.01760940 NA NA
2: 0.147674 0.132956 4325 3460 12 0.02391247 0.03136304 0.02315468
3: 0.235356 0.150813 2703 NA NA 0.03171236 NA NA
4: 1.000000 2.000000 4 NA NA 0.01567365 NA NA
5: 2.000000 1.000000 10 NA NA 0.02314860 NA NA
我的问题是:我的方法可以吗?我不熟悉 dcast
并且符号 x+y ~ NN.counter
让我想知道是否两个不同的点 (x,y) 导致相同的和 x+y 会被认为是不同的(例如第 6 行和第 7 行我的原始数据框,其中 x 和 y 颠倒了)。显然它似乎有效。
有没有人有更好的方法来处理这个重复的问题,或者我的可以吗?另外,我不知道这是否相当快,尽管我读过 data.table
非常快。
由于 x
和 y
都是 numeric
,您可能 运行 遇到基于浮点精度的问题(即 R FAQ 7.31 and IEEE-754) .虽然它可能有效,但我不知道我会严格依赖它(没有大量验证)。在分组和 dcast
ing.
sprintf("%0.06f", x)
)可能很有用(出于重塑的目的)
这里有一个想法可以解决这个问题。 (注意:我使用 magrittr
只是为了用 %>%
管道分解步骤,它不需要运行。)
library(data.table)
library(magrittr)
result <- data.table(x=c(0.147674, 0.235356 ,0.095337, 0.147674, 0.147674, 1.000000, 2.000000), y=c(0.132956, 0.150813, 0.087345, 0.132956, 0.132956, 2.000000, 1.000000), label = c(5,6,5,6,7,3,9), NN.idx =c(4325,2703,21282,3460,12,4,10), dist=c(0.02391247,0.03171236,0.01760940,0.03136304, 0.02315468, 0.01567365, 0.02314860))
result[, c("x_s", "y_s") := lapply(.(x, y), sprintf, fmt = "%0.09f") ]
savexy <- unique(result[, .(x, y, x_s, y_s) ]) # merge back in later with "real" numbers
result2 <- copy(result) %>%
.[, c("x", "y") := NULL ] %>%
.[, NN.counter := seq_len(.N), by = c("x_s", "y_s") ] %>%
dcast(x_s + y_s ~ NN.counter, value.var = c("NN.idx", "dist") ) %>%
merge(., savexy, by = c("x_s", "y_s"), all.x = TRUE) %>%
.[, c("x_s", "y_s") := NULL ] %>%
setcolorder(., c("x", "y"))
result2
# x y NN.idx_1 NN.idx_2 NN.idx_3 dist_1 dist_2 dist_3
# 1: 0.095337 0.087345 21282 NA NA 0.01760940 NA NA
# 2: 0.147674 0.132956 4325 3460 12 0.02391247 0.03136304 0.02315468
# 3: 0.235356 0.150813 2703 NA NA 0.03171236 NA NA
# 4: 1.000000 2.000000 4 NA NA 0.01567365 NA NA
# 5: 2.000000 1.000000 10 NA NA 0.02314860 NA NA