根据数据框中的公共标识符和特定列按比例划分行值

时间:2017-10-23 14:14:23

标签: r dataframe

在合并过程之后,我得到了一个类似于以下内容的数据框:

df <- data.frame(trip=c(315,328,422,422,458,652,652,652,699), 
                 catch_kg=c(10,8,12,2,26,4,18,14,11),
                 age_1=c(0,0,0,0,0,0,0,0,0), 
                 age_2=c(2,1,7.5,7.5,8,11,11,11,13), 
                 id=c(1,2,3,3,4,5,5,5,6))

trip   catch_kg   age_1    age_2   id 
 315      10        0        2      1
 328       8        0        1      2
 422      12        0      7.5      3
 422       2        0      7.5      3
 458      26        0        8      4
 652       4        0       11      5
 652      18        0       11      5
 652      14        0       11      5
 699      11        0       13      6

其中行程表示钓鱼行程, catch_kg 捕获的鱼量(以公斤为单位), age_1 &amp; age_2 是每次旅行和每个年龄段的个人数量, id 表示每次旅行中的运输身份。

在一些钓鱼旅行中,我有超过1次运输 - 可以在 id 列中访问,其中超过1次运输的旅行具有相同的ID号。例如:旅行号码422有两个运输(id = 3)。

此时此刻,对于一次超过1次旅行的旅行,我认为每个年龄组中的人数均等于该特定旅行中出现的拖运数量。例如,在旅行422中,我总共有15个人,但由于有2个人,所以这个数字除以2,每个人有7.5个人。

然而,我想要的是计算每个年龄组中的个体数量,作为每个运输组中总捕获量的比例。 因此,最后我希望有一个看起来像这样的数据框:

trip  catch_kg  age_1   age_2  id 
 315     10       0        2    1
 328      8       0        1    2
 422     12       0       13    3
 422      2       0        2    3
 458     26       0        8    4
 652      4       0        4    5
 652     18       0       16    5
 652     14       0       13    5
 699     11       0       13    6

这基本上是三次计算的规则,例如,对于旅程422(2次运输),我将进行以下计算:

haul1:12 *(7.5 + 7.5)/(12 + 2)= 13个人 haul2:2 *(7.5 + 7.5)/(12 + 2)= 2个人

有没有简单的方法来计算这些计算? 任何帮助将不胜感激。

-M

2 个答案:

答案 0 :(得分:2)

您可以使用dplyr来帮助解决此问题

library(dplyr)
df %>% group_by(trip) %>%
  mutate(age_2=catch_kg/sum(catch_kg)*sum(age_2))
#    trip catch_kg age_1     age_2    id
#   <dbl>    <dbl> <dbl>     <dbl> <dbl>
# 1   315       10     0  2.000000     1
# 2   328        8     0  1.000000     2
# 3   422       12     0 12.857143     3
# 4   422        2     0  2.142857     3
# 5   458       26     0  8.000000     4
# 6   652        4     0  3.666667     5
# 7   652       18     0 16.500000     5
# 8   652       14     0 12.833333     5
# 9   699       11     0 13.000000     6

不确定您使用什么样的舍入规则来获得整数人数,但是在较复杂的情况下,您可能会遇到部分问题,而这些问题并没有增加整体效果。

答案 1 :(得分:1)

另一种使用data.table的解决方案:

library(data.table)
setDT(df)
df[, age_2 := catch_kg * sum(age_2) /  sum(catch_kg), trip]
#  trip catch_kg age_1     age_2 id
#1:  315       10     0  2.000000  1
#2:  328        8     0  1.000000  2
#3:  422       12     0 12.857143  3
#4:  422        2     0  2.142857  3
#5:  458       26     0  8.000000  4
#6:  652        4     0  3.666667  5
#7:  652       18     0 16.500000  5
#8:  652       14     0 12.833333  5
#9:  699       11     0 13.000000  6

如果您愿意,可以使用age_2围绕round()age_2 := round(catch_kg * sum(age_2) / sum(catch_kg))