Tính tổng các hàng dựa trên giá trị cột phù hợp trong R? [bản sao]

Aug 16 2020
        c1       c2       count 
 1        1        1          20
 2        2        3          50 
 3        1        4          30              

Vì vậy, về cơ bản tôi có dữ liệu giống như bảng trên nhưng những gì tôi muốn làm là thêm một cột mới có số lượng mỗi hàng chia cho tổng số lượng của tất cả các hàng có cùng giá trị c1, kết thúc bằng một cái gì đó như:

        c1       c2       count    new_col
 1        1        1          20     20/50
 2        2        3          40     40/40
 3        1        4          30     30/50

Như bạn có thể thấy, cột mới có số lượng của hàng chia cho tổng của tất cả các số lượng có giá trị c1 phù hợp. Vì vậy, những gì tôi đang cố gắng là một cái gì đó như thế này:

df$new_col <- df$count/sum(df[SUBSET OF ROWS THAT HAVE SAME c1 VALUE]$count)

Tôi đã thấy một cái gì đó giống như df [df $ c1 == một số giá trị,] nhưng điều này sẽ chỉ hoạt động đối với một giá trị được mã hóa cứng. Tôi cũng có thể thử sử dụng vòng lặp for, nhưng phải mất quá nhiều thời gian để lặp qua từng hàng đơn lẻ trong dữ liệu của tôi và không bao giờ chạy xong, tôi cũng không biết tất cả các giá trị mà c1 nhận. Tôi còn khá mới với R và có thể có một giải pháp rất đơn giản cho vấn đề này nhưng tôi chưa thể nghĩ ra.

Trả lời

3 Duck Aug 16 2020 at 04:06

Thử cái này:

library(dplyr)
#Data
df <- structure(list(c1 = c(1L, 2L, 1L), c2 = c(1L, 3L, 4L), count = c(20, 
40, 30)), row.names = c("1", "2", "3"), class = "data.frame")

Mật mã:

df %>% group_by(c1) %>% mutate(Sum=sum(count),NewVar=count/Sum)

Đầu ra:

# A tibble: 3 x 5
# Groups:   c1 [2]
     c1    c2 count   Sum NewVar
  <int> <int> <dbl> <dbl>  <dbl>
1     1     1    20    50    0.4
2     2     3    40    40    1  
3     1     4    30    50    0.6
2 ThomasIsCoding Aug 16 2020 at 04:20

Một tùy chọn R cơ sở thông qua ave

> within(df,new_col <- count/ave(count,c1,FUN = sum))
  c1 c2 count new_col
1  1  1    20     0.4
2  2  3    40     1.0
3  1  4    30     0.6

hoặc qua rowsum(bởi @akrun từ bình luận)

> within(df,new_col <- count/rowsum(count,c1)[c1])
  c1 c2 count new_col
1  1  1    20     0.4
2  2  3    40     1.0
3  1  4    30     0.6

Dữ liệu

> dput(df)
structure(list(c1 = c(1L, 2L, 1L), c2 = c(1L, 3L, 4L), count = c(20, 
40, 30)), row.names = c("1", "2", "3"), class = "data.frame")