Sumowanie wierszy na podstawie pasującej wartości kolumny w R? [duplikować]

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

Zasadniczo mam dane takie jak powyższa tabela, ale chcę dodać nową kolumnę, w której liczba każdego wiersza podzielona jest przez sumę wszystkich wierszy o tej samej wartości c1, kończąc na czymś takim:

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

Jak widać, w nowej kolumnie liczba wierszy podzielona jest przez sumę wszystkich zliczeń z pasującą wartością c1. Próbowałem więc coś takiego:

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

Widziałem coś takiego jak df [df $ c1 == jakaś wartość], ale to działałoby tylko dla wartości zakodowanej na stałe. Mógłbym również spróbować użyć pętli for, ale iteracja przez każdy wiersz w moich danych zajmuje zbyt dużo czasu i nigdy nie kończy działania, również nie znam wszystkich wartości, które przyjmuje c1. Jestem całkiem nowy w R i może istnieć bardzo proste rozwiązanie tego problemu, ale nie byłem w stanie go wymyślić.

Odpowiedzi

3 Duck Aug 16 2020 at 04:06

Spróbuj tego:

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")

Kod:

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

Wynik:

# 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

Podstawowa opcja R przez 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

lub przez rowsum(przez @akrun z komentarza)

> 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

Dane

> 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")