Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 使用匹配索引将一个表除以另一个表_R - Fatal编程技术网

R 使用匹配索引将一个表除以另一个表

R 使用匹配索引将一个表除以另一个表,r,R,我有两个带有共享索引的表,我想将它们除以另一个。这可以通过在两个数据帧上进行除法来完成。但它似乎是任意的(我怎么知道我划分的是正确的数字?)并且不保留索引,所以我想通过将行与相同的索引进行匹配来进行此划分。最好的方法是什么?在这种情况下,在表格划分方面是否有最佳实践 tb1 <- data.frame(index = c(1, 2, 3), total_1 = c(100, 450, 300), total_2 = c(20, 39, 60)) tb2 <- data.frame(i

我有两个带有共享索引的表,我想将它们除以另一个。这可以通过在两个数据帧上进行除法来完成。但它似乎是任意的(我怎么知道我划分的是正确的数字?)并且不保留索引,所以我想通过将行与相同的索引进行匹配来进行此划分。最好的方法是什么?在这种情况下,在表格划分方面是否有最佳实践

tb1 <- data.frame(index = c(1, 2, 3), total_1 = c(100, 450, 300), total_2 = c(20, 39, 60))
tb2 <- data.frame(index = c(1, 2, 3), unit_1 = c(4, 2, 3), unit_2 = c(2, 3, 6))
tb1[,-1]/tb2[,-1]
  total_1 total_2
1      25      10
2     225      13
3     100      10

tb1如果两个数据具有相同的索引且行数相同。一种方法是通过“索引”对两个数据进行排序,以确保它们的顺序相同。然后进行除法

tb1new <- tb1[order(tb1$index),]
tbl2new <- tb2[order(tb2$index),]
tb1new[-1] <- tbl1new[-1]/tbl2new[-1]
i1 <- all.equal(tbl1$index, tbl2$index)
if(i1) tb1[-1]/tbl2[-1]

tb1new您可以执行连接和拆分列。在R基中:

result <- merge(tb1, tb2, by = c('index_1', 'index_2'))
result

#  index_1 index_2 total_1 total_2 unit_1 unit_2
#1       a       c     100      20      4      2
#2       b       b     300      60      3      6
#3       b       d     450      39      2      3

total_cols <- grep('total', names(result), value = TRUE)
unit_cols <- grep('unit', names(result), value = TRUE)

result[total_cols]/result[unit_cols]

#  total_1 total_2
#1      25      10
#2     100      10
#3     225      13

result也许这不是最有效的解决方案,但这里有另一种方法:

library(dplyr)
library(tidyr)

# For one index matching

tb1 %>%
  left_join(tb2, by = "index") %>%
  mutate(result_1 = get(paste("total", 1, sep = "_")) / get(paste("unit", 1, sep = "_")),
         result_2 = get(paste("total", 2, sep = "_")) / get(paste("unit", 2, sep = "_")))


  index result_1 result_2
1     1       25       10
2     2      225       13
3     3      100       10

# For two indices matching

tb1 %>%
  left_join(tb2, by = c("index_1", "index_2")) %>%
  mutate(result_1 = get(paste("total", 1, sep = "_")) / get(paste("unit", 1, sep = "_")),
         result_2 = get(paste("total", 2, sep = "_")) / get(paste("unit", 2, sep = "_"))) %>%
  select(!starts_with(c("total", "unit")))

  index_1 index_2 result_1 result_2
1       a       c       25       10
2       b       d      225       13
3       b       b      100       10

你们两个都有索引吗data@akrun是的,两个数据都有索引,顺序相同,但我想确保我明确地执行了这一点,所以您想确保索引行始终匹配吗?
tb1[,-1]/tb2[match(tb1$index,tb2$index),-1]
怎么样?@thelatemail如果我想匹配两列索引,这将如何工作?@KabochaPorter-如果你有多个键,你开始进入仅仅进行连接/合并的领域。我知道akrun已经提出了这个建议。有没有办法保存索引呢?
order
对分类索引有效吗?@kabochapter它将按字母顺序排列。是否要更新“tb1”中的“total”列?@kabochapter如果要按除以的值更新数据,只需在tb1上使用相同的赋值就可以了,替换不是必需的。@kabochapter如果有多个列要匹配,您可以像在更新中一样使用联接,即指定
on=(index\u 1,index\u 2)
result <- merge(tb1, tb2, by = c('index_1', 'index_2'))
result

#  index_1 index_2 total_1 total_2 unit_1 unit_2
#1       a       c     100      20      4      2
#2       b       b     300      60      3      6
#3       b       d     450      39      2      3

total_cols <- grep('total', names(result), value = TRUE)
unit_cols <- grep('unit', names(result), value = TRUE)

result[total_cols]/result[unit_cols]

#  total_1 total_2
#1      25      10
#2     100      10
#3     225      13
library(dplyr)
library(tidyr)

# For one index matching

tb1 %>%
  left_join(tb2, by = "index") %>%
  mutate(result_1 = get(paste("total", 1, sep = "_")) / get(paste("unit", 1, sep = "_")),
         result_2 = get(paste("total", 2, sep = "_")) / get(paste("unit", 2, sep = "_")))


  index result_1 result_2
1     1       25       10
2     2      225       13
3     3      100       10

# For two indices matching

tb1 %>%
  left_join(tb2, by = c("index_1", "index_2")) %>%
  mutate(result_1 = get(paste("total", 1, sep = "_")) / get(paste("unit", 1, sep = "_")),
         result_2 = get(paste("total", 2, sep = "_")) / get(paste("unit", 2, sep = "_"))) %>%
  select(!starts_with(c("total", "unit")))

  index_1 index_2 result_1 result_2
1       a       c       25       10
2       b       d      225       13
3       b       b      100       10