如何计算R中表格中的百分比差异

如何计算R中表格中的百分比差异,r,dataframe,R,Dataframe,我有一个csv文件,其中第1-5行代表一个州,第5-10行代表另一个州,以此类推。。。我还有一个专栏,每个州都重复了19701980年、2010年和2010年。在R中,虽然我不反对Excel中的解决方案,但如果这更简单的话,我希望每个州计算当年与1970年之间的百分比差异,即对于阿拉巴马州1990年,它将是AL 1990-AL 1970/AL 1970,并将其添加到数据表中的新列中,以便我可以将其导出到csv 输出将是一列 我们可以使用data.table。将'data.frame'转换为'da

我有一个csv文件,其中第1-5行代表一个州,第5-10行代表另一个州,以此类推。。。我还有一个专栏,每个州都重复了19701980年、2010年和2010年。在R中,虽然我不反对Excel中的解决方案,但如果这更简单的话,我希望每个州计算当年与1970年之间的百分比差异,即对于阿拉巴马州1990年,它将是AL 1990-AL 1970/AL 1970,并将其添加到数据表中的新列中,以便我可以将其导出到csv

输出将是一列

我们可以使用data.table。将'data.frame'转换为'data.table'setDTdf,按'State'排序,在i中按'State'分组的'Year',获取'Num'与第一个值'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

数据 我们可以使用data.table。将'data.frame'转换为'data.table'setDTdf,按'State'排序,在i中按'State'分组的'Year',获取'Num'与第一个值'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

数据 dplyr包包括函数first,它提供了一种获取组的第一个值的简单方法。因此,如果我们按年份进行安排,使1970年成为每个组的第一个值,当我们按状态分组时,我们可以使用firstNum获得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
dplyr包包括函数first,它提供了一种获取组的第一个值的简单方法。因此,如果我们按年份进行安排,使1970年成为每个组的第一个值,当我们按状态分组时,我们可以使用firstNum获得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
使用tapply的Base R解决方案

使用tapply的Base R解决方案


您好,John,您能提供数据帧或其中的一小部分,以便将其剪切并粘贴到我们的R会话中吗?此外,还提供了一个输出的示例。@Done!您好,John,您能提供数据帧或其中的一小部分,以便将其剪切并粘贴到我们的R会话中吗?此外,还提供了一个输出的示例。@Done!谢谢你的帮助,但我的整个专栏都是NA。。。还有,对不起,我想我的问题有点不清楚。我希望每个值都是自1970年以来的百分比差,因此对于每个分组,我希望减去并除以1970年的值。@JohnSmith前面的例子不在这里。我很感谢你的帮助,但是我得到了整个专栏的NA。。。还有,对不起,我想我的问题有点不清楚。我希望每个值都是自1970年以来的百分比差,因此对于每个分组,我希望减去并除以1970年的值。@JohnSmith前面的例子不在这里。我更新了
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))
# 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
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         20