2

我是 R 新手。我正在使用一个比较面板数据集,其中一个关键变量是时间的横截面,因此我必须对该时间段内的所有变量进行平均。

数据的格式如下:行是国家观察,列是可变年份。

我已经构建了这个例子:

cname<- c("ARGENTINA", "BOLIVIA", "CHILE", "CHINA", "ECUADOR", "EGYPT")
gdp2003<- c(1.5, 2.3, 5.2, 12, 2.3, 3.3)
gdp2004<- c(1.7, 2.2, 4.7, 13.3, 1.7, 1.5)
corrupt2003<- c(5.1, 6.7, 3.4, 5.5, 4.5, 8.7)
corrupt2004<- c(4.5, 5.4, 2.4, 4.5, 5.4, 8.9)
df<- data.frame(cbind(cname, gdp2003, gdp2004, corrupt2003, corrupt2004))
df

生成此输出:

     cname gdp2003 gdp2004 corrupt2003 corrupt2004
1 ARGENTINA     1.5     1.7         5.1         4.5
2   BOLIVIA     2.3     2.2         6.7         5.4
3     CHILE     5.2     4.7         3.4         2.4
4     CHINA      12    13.3         5.5         4.5
5   ECUADOR     2.3     1.7         4.5         5.4
6     EGYPT     3.3     1.5         8.7         8.9

我想创建一个函数,可以按国家 obs 对列变量进行平均,如下所示:

       cname gdp2003 gdp2004 corrupt2003 corrupt2004 new.col.gdp new.col.corrupt
1 ARGENTINA     1.5     1.7         5.1         4.5         1.6             4.8
2   BOLIVIA     2.3     2.2         6.7         5.4        2.25            6.05
3     CHILE     5.2     4.7         3.4         2.4        4.95             2.9
4     CHINA      12    13.3         5.5         4.5       12.65               5
5   ECUADOR     2.3     1.7         4.5         5.4           2            4.95
6     EGYPT     3.3     1.5         8.7         8.9         2.4             8.8

任何帮助,将不胜感激。

4

3 回答 3

3

First you need to change the command creating the data frame. By using cbind() you converted all of your numeric columns to text (to match the cname column which is text. Then R converted those text columns to factors when you made the data.frame. Also change your data.frame name to DF to avoid any conflicts with function df():

DF<- data.frame(cname, gdp2003, gdp2004, corrupt2003, corrupt2004)
vars <-c("gdp","corrupt")
new.cols <- sapply(vars, function(i) rowMeans(DF[, grepl(i, colnames(DF))]))
colnames(new.cols) <- paste0(colnames(new.cols), ".mean")
DF <- data.frame(DF, new.cols)
DF
于 2012-08-07T01:58:01.983 回答
2

您可以只rowMeans在选择列上使用

df$new.col.gdp <- rowMeans(df[,2:3])
df$new.col.corrupt <- rowMeans(df[,3:4])

现在,假设您并不真正了解您想要的所有列的编号,但您碰巧知道它们都将包含名称中常见的内容。假设它是'gdp'。你可以使用类似的东西。

selectColumns <- grep('gdp', names(df))
df$new.col.gdp <- rowMeans(df[,selectColumns])
于 2012-08-07T01:33:44.110 回答
2

虽然到目前为止提供的解决方案肯定会奏效,但我建议以不同的方式构建您的数据。您在这里组合数据和字段名称:与其拥有一个名为“gdp2003”的字段,您实际上应该只拥有一个名为“gdp”的字段并拥有另一个名为“year”的字段,然后记录 gdp 的年份是 2003 年。有关此方法的更多信息,我强烈建议阅读 Hadley Wickham 的论文Tidy Data

以下是如何修改以这种方式设置数据的方法:

df <- data.frame(country=cname, year=2003, gdp=gdp2003,
                 corrupt=corrupt2003)
df <- rbind(df, data.frame(country=cname, year=2004,
                 gdp=gdp2004, corrupt=corrupt2004))

您的数据框现在应该如下所示:

     country year  gdp corrupt
1  ARGENTINA 2003  1.5     5.1
2    BOLIVIA 2003  2.3     6.7
3      CHILE 2003  5.2     3.4
4      CHINA 2003 12.0     5.5
5    ECUADOR 2003  2.3     4.5
6      EGYPT 2003  3.3     8.7
7  ARGENTINA 2004  1.7     4.5
8    BOLIVIA 2004  2.2     5.4
9      CHILE 2004  4.7     2.4
10     CHINA 2004 13.3     4.5
11   ECUADOR 2004  1.7     5.4
12     EGYPT 2004  1.5     8.9

在这种形式中,您会发现以后添加数据要容易得多,并且仍然使用您的代码来计算平均值。一种方法是使用by

by(df[,-(1:2)], df$country, colMeans)

这将为您提供平均值列表:

df$country: ARGENTINA
    gdp corrupt 
    1.6     4.8 
------------------------------------------------------------ 
df$country: BOLIVIA
    gdp corrupt 
   2.25    6.05 

[etc]

你可以把它变成一个更好的表,如下所示:

t(simplify2array(by(df[,-(1:2)], df$country, colMeans)))

            gdp corrupt
ARGENTINA  1.60    4.80
BOLIVIA    2.25    6.05
CHILE      4.95    2.90
CHINA     12.65    5.00
ECUADOR    2.00    4.95
EGYPT      2.40    8.80

要在处理整洁数据时获得更大的灵活性,请查看该plyr软件包。

ddply(df, .(country), summarise, gdp=mean(gdp), corrupt=mean(corrupt))

如果您想要平均值和原始结果(例如,如果您想计算每年的平均值差异):

ddply(df, .(country), transform, gdp.m=mean(gdp), corrupt.m=mean(corrupt))

      country year  gdp corrupt gdp.m corrupt.m
1  ARGENTINA 2003  1.5     5.1  1.60      4.80
2  ARGENTINA 2004  1.7     4.5  1.60      4.80
3    BOLIVIA 2003  2.3     6.7  2.25      6.05
4    BOLIVIA 2004  2.2     5.4  2.25      6.05
5      CHILE 2003  5.2     3.4  4.95      2.90
6      CHILE 2004  4.7     2.4  4.95      2.90
7      CHINA 2003 12.0     5.5 12.65      5.00
8      CHINA 2004 13.3     4.5 12.65      5.00
9    ECUADOR 2003  2.3     4.5  2.00      4.95
10   ECUADOR 2004  1.7     5.4  2.00      4.95
11     EGYPT 2003  3.3     8.7  2.40      8.80
12     EGYPT 2004  1.5     8.9  2.40      8.80
于 2012-08-07T10:09:49.240 回答