我是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
我想创建一个可以按国家/地区平均列变量的函数,如下所示:
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
任何帮助将不胜感激。
答案 0 :(得分:3)
首先,您需要更改创建数据框的命令。通过使用cbind(),您将所有数字列转换为文本(以匹配作为文本的cname列。然后,当您创建data.frame时,R将这些文本列转换为因子。还要将data.frame名称更改为DF避免与函数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
答案 1 :(得分: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])
答案 2 :(得分:2)
虽然到目前为止提供的解决方案肯定会有用,但我建议以不同的方式构建数据。你在这里组合数据和字段名称:而不是有一个名为&#34; gdp2003&#34;的字段,你应该只有一个名为&#34; gdp&#34;的字段。还有一个名为&#34; year&#34;然后有一个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