Условный расчет в R на основе значений и категорий строк

У меня есть этот кадр данных:

df<-data.frame(a=c("a1","a2","a3","a4","b1","b2","b3","b4","a1","a2","a3","a4","b1","b2","b3","b4"), b=c("x1","x2","x3","total","x1","x2","x3","total", "x1","x2","x3","total","x1","x2","x3","total"), reg=c("A","A","A","A","A","A","A","A","B", "B","B","B","B","B","B","B"), c=c(1:16))

который выглядит так:

    a     b reg  c
1  a1    x1   A  1
2  a2    x2   A  2
3  a3    x3   A  3
4  a4 total   A  4
5  b1    x1   A  5
6  b2    x2   A  6
7  b3    x3   A  7
8  b4 total   A  8
9  a1    x1   B  9
10 a2    x2   B 10
11 a3    x3   B 11
12 a4 total   B 12
13 b1    x1   B 13
14 b2    x2   B 14
15 b3    x3   B 15
16 b4 total   B 16

столбцы «a», «b» и «reg» являются категориальными переменными. Что я хочу сделать, так это создать новый столбец, который делит x (i), где i = 1,2,3 с «итогом» (x (i) / total) для каждой категории в столбцах reg' and ina.

Может кто-то помочь мне с этим ?


person user17880    schedule 11.10.2017    source источник


Ответы (2)


Предполагая, что ваш df упорядочен, как ваш пример.

library(zoo)
df$NEW=df$c
df$NEW[df$b!='total']=NA
df$NEW=na.locf(df$NEW,fromLast=T,na.rm=F)
df$NEW=df$c/df$NEW

df
    a     b reg  c       NEW
1  a1    x1   A  1 0.2500000
2  a2    x2   A  2 0.5000000
3  a3    x2   A  3 0.7500000
4  a4 total   A  4 1.0000000
5  b1    x1   A  5 0.6250000
6  b2    x2   A  6 0.7500000
7  b3    x2   A  7 0.8750000
8  b4 total   A  8 1.0000000
9  a1    x1   B  9 0.7500000
10 a2    x2   B 10 0.8333333
11 a3    x2   B 11 0.9166667
12 a4 total   B 12 1.0000000
13 b1    x1   B 13 0.8125000
14 b2    x2   B 14 0.8750000
15 b3    x2   B 15 0.9375000
16 b4 total   B 16 1.0000000

Основываясь на объяснении Оп, ниже приведены реальные данные о нем / ней (из ОП).

data1$shares<-NA 
id<-which(data1$Occupation=='Total') 
data1$shares[id]<-data1$2014[id]
data1$shares=na.locf(data1$shares,fromLast=T,na.rm=F) 
data1$shares=data1$2014/data1$shares
person BENY    schedule 11.10.2017
comment
почему-то не работал. Это потому, что есть случаи, когда total равно NAN, тогда как столбец «c» может также включать значения «NAN»? - person user17880; 11.10.2017
comment
@user17880 user17880, если общее количество NA, как вы с этим связаны - person BENY; 11.10.2017
comment
в идеале в этом примере он должен возвращать 'NA'. - person user17880; 11.10.2017
comment
@ user17880 Я добавлю df$NEW[df$b=='total'&is.na(df$NEW)]=-1 и в конце добавлю df$NEW[df$NEW<0]=NA - person BENY; 11.10.2017
comment
Тем не менее, не работал. Но я обнаружил, что эта модификация вашего кода работает для моей цели: 'data1$shares‹-NA id‹-what(data1$Occupation=='Total') data1$shares[id]‹-data1$2014[id ] data1$shares=na.locf(data1$shares,fromLast=T,na.rm=F) data1$shares=data1$2014/data1$shares' - person user17880; 11.10.2017
comment
@user17880 user17880, пока проблема решена :) приветствую, доброе напоминание, в следующий раз предоставьте воспроизводимый пример, иначе у вас будет та же проблема, решение для выборки данных не работает для реальных данных - person BENY; 11.10.2017
comment
@ user17880 также Если хотите, вы можете пометить это как ответ. Или, может быть, изменить исходный пост в соответствии с упомянутым вами случаем, я либо удалю этот ответ, либо изменю его. - person BENY; 11.10.2017
comment
Нет, лучше изменить свой ответ. Я думаю, что вы заслуживаете большей похвалы :) - person user17880; 11.10.2017
comment
@ user17880 просто отредактируйте и упомяните, что это от вас :-) - person BENY; 11.10.2017

Просто используя базу R:

df<-data.frame(a=c("a1","a2","a3","a4","b1","b2","b3","b4","a1","a2","a3","a4","b1","b2","b3","b4"), b=c("x1","x2","x3","total","x1","x2","x3","total", "x1","x2","x3","total","x1","x2","x3","total"), reg=c("A","A","A","A","A","A","A","A","B", "B","B","B","B","B","B","B"), c=c(1:16))

totals <- data.frame(To=df[df$b=='total',4])
totals$from <- c(1, totals$To[1:nrow(totals)-1]+1)
df$NEW = df$c/totals[findInterval(x=df$c, vec=c(rbind(totals$from, totals$to))), 1]
df

Выход:

    a     b reg  c       NEW
1  a1    x1   A  1 0.2500000
2  a2    x2   A  2 0.5000000
3  a3    x3   A  3 0.7500000
4  a4 total   A  4 1.0000000
5  b1    x1   A  5 0.6250000
6  b2    x2   A  6 0.7500000
7  b3    x3   A  7 0.8750000
8  b4 total   A  8 1.0000000
9  a1    x1   B  9 0.7500000
10 a2    x2   B 10 0.8333333
11 a3    x3   B 11 0.9166667
12 a4 total   B 12 1.0000000
13 b1    x1   B 13 0.8125000
14 b2    x2   B 14 0.8750000
15 b3    x3   B 15 0.9375000
16 b4 total   B 16 1.0000000
person Patricio Moracho    schedule 11.10.2017