Суммирование значений в одном столбце на основе уникальных значений в другом столбце
Я пытаюсь добавить значения в столбце C на основе уникальных значений в столбце B. Например, для B = 1 я хотел бы добавить все строки в столбце C, то есть 5+4+3=12.
A B C
1 1 5
2 1 4
3 1 3
4 2 1
5 2 3
for(i in unique(df$B)){
df$D = sum(df$C)
}
Кроме того, я хотел бы добавить количество раз, когда каждый столбец B встречается с данными.
Решение:
A B C D E
1 1 5 12 3
2 1 4 12 3
3 1 3 12 3
4 2 1 4 2
5 2 3 4 2
пример из моей задачи:
docIdx newsgroup_ID freq
1 1 768
2 1 125
3 1 29
4 1 51
5 1 198
6 1 34
7 1 64
8 2 35
9 2 70
10 2 45
5 ответов
В базе R вы можете использовать ave
df[, c("D", "E")] <- with(df, sapply(c(sum, length), function(x) ave(C, B, FUN = x)))
df
# A B C D E
#1 1 1 5 12 3
#2 2 1 4 12 3
#3 3 1 3 12 3
#4 4 2 1 4 2
#5 5 2 3 4 2
Или используя dplyr
library(dplyr)
df <- df %>%
group_by(B) %>%
mutate(D = sum(C), E = length(C))
df
## A tibble: 5 x 5
## Groups: B [2]
# A B C D E
# <int> <int> <int> <int> <int>
#1 1 1 5 12 3
#2 2 1 4 12 3
#3 3 1 3 12 3
#4 4 2 1 4 2
#5 5 2 3 4 2
Пример данных
df <- read.table(text =
"A B C
1 1 5
2 1 4
3 1 3
4 2 1
5 2 3", header = T)
Он работает отлично с вашими пересмотренными данными
df <- read.table(text =
"docIdx newsgroup_ID freq
1 1 768
2 1 125
3 1 29
4 1 51
5 1 198
6 1 34
7 1 64
8 2 35
9 2 70
10 2 45", header = T)
df[, c("sum.freq", "length.freq")] <- with(df, sapply(c(sum, length), function(x)
ave(freq, newsgroup_ID, FUN = x)))
# docIdx newsgroup_ID freq sum.freq length.freq
#1 1 1 768 1269 7
#2 2 1 125 1269 7
#3 3 1 29 1269 7
#4 4 1 51 1269 7
#5 5 1 198 1269 7
#6 6 1 34 1269 7
#7 7 1 64 1269 7
#8 8 2 35 150 3
#9 9 2 70 150 3
#10 10 2 45 150 3
Вот ave(freq, newsgroup_ID, FUN = x)
применяет функцию x
в freq
от newsgroup_ID
,
B <- c(1,1,1,2,2)
C <- c(5,4,3,1,3)
x <- cbind(B,C)
sum <- 0
for (i in 1:nrow(x)) {
if (x[i] == 1) {
sum <- x[i, 2] + sum
}
sum
}
Я надеюсь, что это поможет вам.
Если вы хотите сделать ту же логику, используя условие цикла
for (i in unique (df$B)){
xx <- sum(df$C[df$B==i])
yy <- length(df$C[df$B==i])
df$D[df$B==i] <- xx
df$E[df$B==i] <- yy
}
print(df)
A B C D E
1 1 1 5 12 3
2 2 1 4 12 3
3 3 1 3 12 3
4 4 2 1 4 2
5 5 2 3 4 2
B <- c(1,1,1,2,2)
C <- c(5,4,3,1,3)
x <- cbind(B,C)
holder1 <- c()
holder2 <- c()
for (num in unique(x[,1])) {
sum <- 0
count <- 0
for (i in 1:nrow(x)) {
if (x[i] == num) {
sum <- x[i, 2] + sum
count <- 1 + count
}
}
print(count)
holder1 <- c(holder1, rep(count, count))
holder2 <- c(holder2, rep(sum, count))
}
x <- as.data.frame(x)
x <- add_column(x, E = holder1, .after = "C")
x <- add_column(x, D = holder2, .after = "C")
> x
B C D E
1 1 5 12 3
2 1 4 12 3
3 1 3 12 3
4 2 1 4 2
5 2 3 4 2
Примечание. Убедитесь, что у нас одинаковые переменные. (поймите код) Я не знаю высокоуровневых функций, поэтому я использовал основные.
Вы можете aggregate
затем merge
результат с исходным фреймом данных:
df <- read.table(text="A B C
1 1 5
2 1 4
3 1 3
4 2 1
5 2 3", header = TRUE)
merge(df, aggregate(C ~ B, df, FUN = function(x) c(sum=sum(x), length=length(x))), by = "B")
#> B A C.x C.y.sum C.y.length
#> 1 1 1 5 12 3
#> 2 1 2 4 12 3
#> 3 1 3 3 12 3
#> 4 2 4 1 4 2
#> 5 2 5 3 4 2
Создано 2019-02-18 пакетом представлением (v0.2.1)