最近有个培训班的小伙伴遇到了这样的问题,他想对字符串变量进行分组求和与分组累加,但是他不知道该如何实现,今天我们就来一起看一下。
Stata 的实现 首先我们先生成一份示例数据:
* 生成示例数据 clear input int group int x str1 y 1 12 "A" 1 2 "B" 1 35 "C" 1 56 "D" 1 34 "E" 1 24 "F" 1 87 "G" 2 1 "a" 2 36 "b" 2 78 "c" 2 34 "d" 2 12 "e" 2 3 "f" 2 0 "g" end list, sep(7) *> +----------------+ *> | group x y | *> |----------------| *> 1. | 1 12 A | *> 2. | 1 2 B | *> 3. | 1 35 C | *> 4. | 1 56 D | *> 5. | 1 34 E | *> 6. | 1 24 F | *> 7. | 1 87 G | *> |----------------| *> 8. | 2 1 a | *> 9. | 2 36 b | *> 10. | 2 78 c | *> 11. | 2 34 d | *> 12. | 2 12 e | *> 13. | 2 3 f | *> 14. | 2 0 g | *> +----------------+
其中 group 变量是分组变量,x 是数值型变量,y 是字符型变量。
对于数值型变量,egen 的 sum() 函数可以实现分组求和的功能:
bysort group: egen xsum = sum (x)list , sep(7)
gen 的 sum() 函数可以实现分组累加的功能:
bysort group: gen xcumsum = sum (x)list , sep(7)
但是上面两个都不能应用与字符串变量,但是字符串变量的加法在 Stata 中是可行的,例如:
gen yy = y + ylist , sep(7)
那我们如何在字符串变量上实现分组求和以及分组累加的功能呢?
可以通过设计下面的命令实现:
实现 egen 的 sum() 功能,也就是分组求和:
gen ysum = "" levelsof group, local (group)foreach i in `group' { di "`i'" local `i' = "" forval j = 1/`=_N'{ if `=group[`j' ]' == `i' { local `i' = "``i''`=y[`j']'" } } replace ysum = "``i''" if group == `i' } list , sep(7)
实现 gen 的 sum() 功能,也就是分组累加:
gen ycumsum = "" levelsof group, local (group)foreach i in `group' { local `i' = "" forval j = 1/`=_N'{ if `=group[`j' ]' == `i' { local `i' = "``i''`=y[`j']'" } replace ycumsum = "``i''" if group == `i' & _n == `j' } } list , sep(7)
这样就完成了!
R 语言的实现 使用 R 语言完成这个工作更容易些,首先我们读取上面生成的示例数据:
library( tidyverse) haven:: read_dta( 'strsum.dta' ) -> df df
x 变量是数值型变量,分组求和或累加都很容易:
df %>% group_by( group) %>% mutate( xsum = sum ( x) ) %>% mutate( xcumsum = cumsum ( x) ) %>% ungroup( )
那么对于字符串变量 y 该如何分组求和(连接)或者累加(逐次连接)呢?
根据我的经验,分组求和很简单:
df %>% group_by( group) %>% mutate( ysum = paste0( y, collapse = "" ) )
分组累加我们先找一个向量试试:
letters letters2 <- c ( ) for ( i in 1 : length ( letters ) ) { letters2[ i] <- paste0( letters [ 1 : i] , collapse = "" ) } letters2
这样我们就可以自己编写一个函数:
strcumsum <- function ( x) { c <- c ( ) for ( i in 1 : length ( x) ) { c [ i] <- paste0( x[ 1 : i] , collapse = "" ) } return ( c ) } strcumsum( letters )
然后就可以用这个函数对字符串变量进行分组累加了:
df %>% group_by( group) %>% mutate( ysum = paste0( y, collapse = "" ) ) %>% mutate( ycumsum = strcumsum( y) )
点击这里跳转到 RStata 短书平台获取附件:R语言 & Stata:如何对字符串变量实现分组求和和分组累加?
评论