Pet*_*Pan 3 r plyr dataframe data.table
我试图在不同因素的数据框中得到一些变量的均值.说我有:
time geo var1 var2 var3 var4
1 1990 AT 1 7 13 19
2 1991 AT 2 8 14 20
3 1992 AT 3 9 15 21
4 1990 DE 4 10 16 22
5 1991 DE 5 11 17 23
6 1992 DE 6 12 18 24
Run Code Online (Sandbox Code Playgroud)
而且我要:
time geo var1 var2 var3 var4 m_var2 m_var3
1 1990 AT 1 7 13 19 8 14
2 1991 AT 2 8 14 20 8 14
3 1992 AT 3 9 15 21 8 14
4 1990 DE 4 10 16 22 11 17
5 1991 DE 5 11 17 23 11 17
6 1992 DE 6 12 18 24 11 17
Run Code Online (Sandbox Code Playgroud)
我用by()和lapply()尝试过一些东西,但我认为这是ddply的方向
require(plyr)
Dataset <- data.frame(time=rep(c(1990:1992),2),geo=c(rep("AT",3),rep("DE",3))
,var1=as.numeric(c(1:6)),var2=as.numeric(c(7:12)),var3=as.numeric(c(13:18)),
var4=as.numeric(c(19:24)))
newvars <- c("var2","var3")
newData <- Dataset[,c("geo",newvars)]
Run Code Online (Sandbox Code Playgroud)
目前,我可以选择两个错误:
ddply(newData,newData[,"geo"],colMeans)
#where R apparently thinks AT is the variable?
ddply(newData,"geo",colMeans)
#where R worries about the factor variable not being numeric?
Run Code Online (Sandbox Code Playgroud)
我的lapply尝试让我走得很远,但后来给我留下了一个我无法回到数据框的列表:
lapply(newvars,function(x){
by(Dataset[x],Dataset[,"geo"],function(x)
rep(colMeans(x,na.rm=T),length(unique(Dataset[,"time"]))))
})
Run Code Online (Sandbox Code Playgroud)
我认为这里必须能够使用合并和过滤器: 使用过滤器在不同变量的数据框中提供,但我无法将它们结合在一起.任何帮助,将不胜感激!
其他方法用 dplyr
library(dplyr)
df1 %>% group_by(geo) %>% mutate(m_var2=mean(var2), m_var3=mean(var3))
Run Code Online (Sandbox Code Playgroud)
另一个简单的基础R解决方案就是
transform(df, m_var2 = ave(var2, geo), m_var3 = ave(var3, geo))
# time geo var1 var2 var3 var4 m_var2 m_var3
# 1 1990 AT 1 7 13 19 8 14
# 2 1991 AT 2 8 14 20 8 14
# 3 1992 AT 3 9 15 21 8 14
# 4 1990 DE 4 10 16 22 11 17
# 5 1991 DE 5 11 17 23 11 17
# 6 1992 DE 6 12 18 24 11 17
Run Code Online (Sandbox Code Playgroud)
几年后,我认为更简洁的方法是更新实际数据集(而不是创建新数据集)并对列向量进行操作(而不是手动编写它们)
vars <- paste0("var", 2:3) # Select desired cols
df[paste0("m_", vars)] <- lapply(df[vars], ave, df[["geo"]]) # Loop and update
Run Code Online (Sandbox Code Playgroud)
一种选择是使用data.table.我们可以转换data.frame到data.table(setDT(df1)),获得mean(lapply(.SD, mean))通过指定的列索引选中的列("VAR2"和"VAR3") .SDcols,由"地缘"分组.通过将output(:=)分配给新列名称(paste('m', names(df1)[4:5]))来创建新列
library(data.table)
setDT(df1)[, paste('m', names(df1)[4:5], sep="_") :=lapply(.SD, mean)
,by = geo, .SDcols=4:5]
# time geo var1 var2 var3 var4 m_var2 m_var3
#1: 1990 AT 1 7 13 19 8 14
#2: 1991 AT 2 8 14 20 8 14
#3: 1992 AT 3 9 15 21 8 14
#4: 1990 DE 4 10 16 22 11 17
#5: 1991 DE 5 11 17 23 11 17
#6: 1992 DE 6 12 18 24 11 17
Run Code Online (Sandbox Code Playgroud)
注意:此方法更通用.我们mean甚至可以为100个变量创建列,而不会对代码进行任何重大更改.即.如果我们需要获得mean列4:100,请更改.SDcols=4:100和paste('m', names(df1)[4:100].
df1 <- structure(list(time = c(1990L, 1991L, 1992L, 1990L, 1991L, 1992L
), geo = c("AT", "AT", "AT", "DE", "DE", "DE"), var1 = 1:6, var2 = 7:12,
var3 = 13:18, var4 = 19:24), .Names = c("time", "geo", "var1",
"var2", "var3", "var4"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1964 次 |
| 最近记录: |