在两个数据框与另一个数组中的元素相等的情况下关联索引

时间:2018-09-16 15:19:39

标签: arrays r dataframe vectorization

我有一个数组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)。

所以基本上,我想知道是否可以在没有循环的情况下并尽可能地通用。

1 个答案:

答案 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