我有一个数组cluster_true
和一个数据帧data
,每行包含一个2D坐标。我想在另一个数据帧中保存有关给定2D坐标多少次出现在cluster_true
中的每个元素的信息。因此,例如,对于坐标(1,1),我要检查data
中前两列的值为1
的所有行,然后检查{{1 }}。这是一个使它更清晰的示例(它给出了所需的结果):
cluster_true
我需要更改的东西,我不知道该怎么做:
# Example variables
cluster_true = c(1,2,1,1,2,2,1,2,2,2,2,1,1)
x = 3
y = 3
data = data.frame(X = c(1,1,0,0,2,1,1,0,0,0,1,1,1),
Y = c(1,1,2,1,2,2,1,0,0,0,0,2,0))
# Names of the columns
plot_colnames = c('X', 'Y', paste('cluster',unique(cluster_true),sep='_'))
# Empty dataframe with the right column names
plot_df = data.frame(matrix(vector(), x*y, length(plot_colnames),
dimnames=list(c(), plot_colnames)),
stringsAsFactors=F)
# Each row belongs to a certain 2D coordinate
plot_df$X = rep(1:x, y)-1
plot_df$Y = rep(1:x, each = y)-1
# This is what I don't know how to improve
for(i in 1:nrow(plot_df)){
idx = which(apply(data[,1:2], 1, function(x) all(x == plot_df[i,1:2])))
plot_df[i,3] = sum(cluster_true[idx] == 1)
plot_df[i,4] = sum(cluster_true[idx] == 2)
}
print(plot_df)
可能有很多行,因此高效的代码将很棒。data
中存在哪些数字以及它们对应于cluster_true
的哪一列)。实际上,plot_df
中的元素可以是任何东西,甚至可以是非连续数字(即cluster_true
)。所以基本上,我想知道是否可以在没有循环的情况下并尽可能地通用。
答案 0 :(得分:1)
如果我理解正确,则OP希望
X, Y
中为data
坐标的所有唯一组合找到行索引,cluster_true
的相应行中查找值,X, Y
组合中每个值的出现次数,并且这可以通过加入并重塑来解决:
library(data.table) # version 1.11.4 used
library(magrittr) # use piping to improve readability
# unique coordinate pairs
uni_coords <- unique(setDT(data)[, .(X, Y)])[order(X, Y)]
# join and lookup values in cluster_true
data[uni_coords, on = .(X, Y), cluster_true[.I], by = .EACHI] %>%
# reshape from long to wide format, thereby counting occurrences
dcast(X + Y ~ sprintf("cluster_%02i", V1), length)
X Y cluster_01 cluster_02 1: 1 1 2 1 2: 1 2 1 1 3: 1 3 1 1 4: 2 2 0 1 5: 3 1 1 0 6: 3 2 1 0 7: 3 3 0 3
这与OP的预期结果相同,只是坐标组合没有出现在data
中。
setDT(plot_df)[order(X, Y)]
X Y cluster_1 cluster_2 1: 1 1 2 1 2: 1 2 1 1 3: 1 3 1 1 4: 2 1 0 0 5: 2 2 0 1 6: 2 3 0 0 7: 3 1 1 0 8: 3 2 1 0 9: 3 3 0 3
重塑的好处是可以按照OP的要求处理cluster_true
中的任意值。
OP has requested中应将X, Y
坐标的所有可能组合都包括在最终结果中。这可以通过使用交叉连接 CJ()
计算uni_coords
来实现:
# all possible coordinate pairs
uni_coords <- setDT(data)[, CJ(X = X, Y = Y, unique = TRUE)]
# join and lookup values in cluster_true
data[uni_coords, on = .(X, Y), cluster_true[.I], by = .EACHI][
uni_coords, on = .(X, Y)] %>%
# reshape from long to wide format, thereby counting occurrences
dcast(X + Y ~ sprintf("cluster_%02i", V1), length) %>%
# remove NA column from reshaped result
.[, cluster_NA := NULL] %>%
print()
X Y cluster_01 cluster_02 1: 1 1 2 1 2: 1 2 1 1 3: 1 3 1 1 4: 2 1 0 0 5: 2 2 0 1 6: 2 3 0 0 7: 3 1 1 0 8: 3 2 1 0 9: 3 3 0 3