我有一个csv文件,其中行1-5代表一种状态,5-10代表另一种状态,等等.我还有一个列,每个州都重复了几年的1970,1980,..,2010。在R中(虽然我不反对在Excel中使用更简单的解决方案),但我希望每个州都计算出该年与1970年之间的百分比差,即对于Alabama 1990,它将是(AL 1990 - AL 1970)/(AL 1970),并将其添加到数据表中的一个新列中,以便将其导出到csv。
State, Year, Num
AL, 1970, 1
AL, 1980, 2
AL, 1990, 3
AL, 2000, 4
AL, 2010, 6 输出将是一个列
pct_change
0
1
2
3
5发布于 2019-04-22 17:17:22
dplyr包包括函数first,它为获取组的第一个值提供了一种简单的方法。因此,如果我们通过Year安排使1970年成为每个组的第一个值,那么当我们group_by(State)时,我们可以使用first(Num)得到Num的第一个值,它代表1970年的值:
# Example data with 2 states
df <- structure(list(State = c("AL", "AL", "AL", "AL", "AL", "TX",
"TX", "TX", "TX", "TX"), Year = c(1970L, 1980L, 1990L, 2000L,
2010L, 1970L, 1980L, 1990L, 2000L, 2010L), Num = c(1, 2, 3, 4,
6, 5, 2, 10, 12, 6)), class = "data.frame", row.names = c(NA,
-10L))
library(dplyr)
df %>%
arrange(State, Year) %>%
group_by(State) %>%
mutate(perc_diff = 100 * (Num - first(Num))/first(Num))
# A tibble: 10 x 4
# Groups: State [2]
State Year Num perc_diff
<chr> <int> <dbl> <dbl>
1 AL 1970 1 0
2 AL 1980 2 100
3 AL 1990 3 200
4 AL 2000 4 300
5 AL 2010 6 500
6 TX 1970 5 0
7 TX 1980 2 -60
8 TX 1990 10 100
9 TX 2000 12 140
10 TX 2010 6 20发布于 2019-04-22 16:55:42
我们可以使用data.table。将“data.frame”转换为“data.table”(setDT(df)),将“i”中的“order”按“i”按“State”分组,得到“Num”与first值“Num”的差异,并分配(:=)以创建“perc_diff”
library(data.table)
setDT(df)[order(State, Year), perc_diff :=
100 * (Num - first(Num))/first(Num), State][]
# State Year Num perc_diff
# 1: AL 1970 1 0
# 2: AL 1980 2 100
# 3: AL 1990 3 200
# 4: AL 2000 4 300
# 5: AL 2010 6 500
# 6: TX 1970 5 0
# 7: TX 1980 2 -60
# 8: TX 1990 10 100
# 9: TX 2000 12 140
#10: TX 2010 6 20或者使用base R
v1 <- with(df, ave(Num, State, FUN = function(x) x[1]))
df$perc_diff <- with(df, 100 * (Num - v1)/v1)数据
df <- structure(list(State = c("AL", "AL", "AL", "AL", "AL", "TX",
"TX", "TX", "TX", "TX"), Year = c(1970L, 1980L, 1990L, 2000L,
2010L, 1970L, 1980L, 1990L, 2000L, 2010L), Num = c(1, 2, 3, 4,
6, 5, 2, 10, 12, 6)), class = "data.frame", row.names = c(NA,
-10L))发布于 2019-04-22 18:24:13
使用R的基本tapply解决方案
df <- df[with(df, order(State, Year)), ]
df$pct_change <- unlist( tapply(df$Num, df$State, function(x) 100 * (x - x[1]) / x[1]) )
> df
State Year Num pct_change
1 AL 1970 1 0
2 AL 1980 2 100
3 AL 1990 3 200
4 AL 2000 4 300
5 AL 2010 6 500
6 TX 1970 5 0
7 TX 1980 2 -60
8 TX 1990 10 100
9 TX 2000 12 140
10 TX 2010 6 20https://stackoverflow.com/questions/55797958
复制相似问题