[英]How do I create a new data.frame with the same column names and types as an existing data.frame?
[英]How do I create a column of means of specific columns in a data.frame?
感謝您的答復和回答。 我可以看到我無意中遺漏了一些重要的細節,可以幫助您更好地理解我的問題。 我試圖使它簡單和通用,但這實際上沒有幫助。 這是具有更多信息的更新版本。
我有一個data.frame
,其中有許多列來自BehaviorSpace
生成的NetLogo
模型。 每列都是一個時間序列,表示在不同實驗條件下的報告值,重復次數由運行編號和時間步長編號表示。 例如(很抱歉,這個時間很長,但是我想為您介紹一下數據):
# Start by building a fake data.frame that models some of the characteristics of mine:
df <- data.frame(run = c(rep(1,5), rep(2,5), rep(3,5), rep(4,5), rep(5,5), rep(6,5), rep(7,5), rep(8,5)))
df2 <- expand.grid(step = 1:5, fac.a = c(10,1000), fac.b = c(0.5,2.0))
df <- data.frame(run = df$run, rep = c(rep(1,20), rep(2,20)), step = df2$step, fac.a = df2$fac.a, fac.b = df2$fac.b)
log_growth <- function (a, b, x) {(1/(1+a*exp(-b*x))) + rnorm(1,0,0.2)}
set.seed(11)
df$treatment1 <- log_growth(df$fac.a, df$fac.b, df$step)
df$treatment2 <- log_growth(df$fac.a / 2, df$fac.b * 2, df$step)
這會將以下內容放入df中:
> df
run rep step fac.a fac.b treatment1 treatment2
1 1 1 1 10 0.5 0.05288201 0.356176584
2 1 1 2 10 0.5 0.12507561 0.600407158
3 1 1 3 10 0.5 0.22081815 0.804671117
4 1 1 4 10 0.5 0.33627099 0.920093934
5 1 1 5 10 0.5 0.46053940 0.971397427
6 2 1 1 1000 0.5 -0.08700866 0.009396323
7 2 1 2 1000 0.5 -0.08594375 0.018552055
8 2 1 3 1000 0.5 -0.08419297 0.042608835
9 2 1 4 1000 0.5 -0.08131981 0.102435481
10 2 1 5 1000 0.5 -0.07661880 0.232875872
11 3 1 1 10 2.0 0.33627099 0.920093934
12 3 1 2 10 2.0 0.75654214 1.002314651
13 3 1 3 10 2.0 0.88715737 1.003958435
14 3 1 4 10 2.0 0.90800192 1.003988593
15 3 1 5 10 2.0 0.91089154 1.003989145
16 4 1 1 1000 2.0 -0.08131981 0.102435481
17 4 1 2 1000 2.0 -0.03688314 0.860350536
18 4 1 3 1000 2.0 0.19880473 1.000926458
19 4 1 4 1000 2.0 0.66014952 1.003932891
20 4 1 5 1000 2.0 0.86791705 1.003988125
21 5 2 1 10 0.5 0.05288201 0.356176584
22 5 2 2 10 0.5 0.12507561 0.600407158
23 5 2 3 10 0.5 0.22081815 0.804671117
24 5 2 4 10 0.5 0.33627099 0.920093934
25 5 2 5 10 0.5 0.46053940 0.971397427
26 6 2 1 1000 0.5 -0.08700866 0.009396323
27 6 2 2 1000 0.5 -0.08594375 0.018552055
28 6 2 3 1000 0.5 -0.08419297 0.042608835
29 6 2 4 1000 0.5 -0.08131981 0.102435481
30 6 2 5 1000 0.5 -0.07661880 0.232875872
31 7 2 1 10 2.0 0.33627099 0.920093934
32 7 2 2 10 2.0 0.75654214 1.002314651
33 7 2 3 10 2.0 0.88715737 1.003958435
34 7 2 4 10 2.0 0.90800192 1.003988593
35 7 2 5 10 2.0 0.91089154 1.003989145
36 8 2 1 1000 2.0 -0.08131981 0.102435481
37 8 2 2 1000 2.0 -0.03688314 0.860350536
38 8 2 3 1000 2.0 0.19880473 1.000926458
39 8 2 4 1000 2.0 0.66014952 1.003932891
40 8 2 5 1000 2.0 0.86791705 1.003988125
因此,我之前所做的是使用by
拆分數據幀by
並希望獲得每個步驟(這是一個時間序列)和每個因子組合的平均值和標准差。
在查看了所有答案並重新考慮了我的問題之后,我認為在by
的轉換過程中可以更好地處理我要嘗試執行的操作。 我不確定該怎么做...我希望輸出看起來像是一個摘要:
> df
run fac.a fac.b mean.treatment1 mean.treatment2 sd.treatment1 sd.treatment2
1 1 10 0.5 xxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx
1 1 10 2.0 xxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx
1 1 1000 0.5 xxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx
1 1 1000 2.0 xxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx
這是aggregate
的工作嗎? 感謝您的耐心配合和幫助。 -格倫
原始問題:
我有一個包含許多列的data.frame
,每列代表一個具有重復的特定實驗條件。
> df <- data.frame(a.1 = runif(5), b.1 = runif(5), a.2 = runif(5), b.2 = runif(5), mean.a = 0, mean.b = 0, mean.1 = 0, mean.2 = 0)
> df
a.1 b.1 a.2 b.2 mean.a mean.b sd.a sd.b
1 0.9209433 0.3501444 0.3893140 0.3264827 0 0 0 0
2 0.4171254 0.4883140 0.8282384 0.1215129 0 0 0 0
3 0.2291582 0.9419946 0.4089008 0.5665242 0 0 0 0
4 0.3807868 0.1889066 0.8271075 0.4022014 0 0 0 0
5 0.5863078 0.4991847 0.4082745 0.5637367 0 0 0 0
我想找到每種條件和重復的均值和標准差。 到目前為止,最直接的方法似乎是:
for (i in c("a.1", "a.2") {df$mean.a <- df$mean.a + df[[i]]}
df$mean.a <- df$mean.a / 2
但是我有很多專欄,而且到處都是,所以這看起來真的很耗費人工。 更好的方法是使用ave()
:
df$mean.a <- with (df, ave(a.1, a.2))
但是,如果我想做sd(),我會神秘地得到NA:
df$sd.a <- with (df, ave(a.1, a.2, FUN = sd))
> df
a.1 b.1 a.2 b.2 mean.a mean.b sd.a sd.b
1 0.9209433 0.3501444 0.3893140 0.3264827 0.9209433 0 NA 0
2 0.4171254 0.4883140 0.8282384 0.1215129 0.4171254 0 NA 0
3 0.2291582 0.9419946 0.4089008 0.5665242 0.2291582 0 NA 0
4 0.3807868 0.1889066 0.8271075 0.4022014 0.3807868 0 NA 0
5 0.5863078 0.4991847 0.4082745 0.5637367 0.5863078 0 NA 0
如果可能的話,我寧願不要使用外部軟件包,但是似乎我缺少一些基本的東西。 這個問題是相似的,但是與data.tables有關,而不與data.frames有關。
另一個甚至更接近,但是使用ave()來指定列1-12、15-17和26作為主題列也很繁瑣,而sd()
神秘地產生了這些NA。 似乎應該有一種簡單的方法來執行此操作。 幾乎讓我希望得到Excel。 :-)
讓我們首先將您的數據轉換為可接受的格式。 請注意,此解決方案確實違反了您的最初要求,確實依賴於外部庫,但是今天它們是非常普遍且真正的節省時間! (Ryr社區中的一種現象Hadley Wickham撰寫的plyr and reshape2)
# Note how I only used the data columns, initially, there is no mean and sd column in the data frame used at this stage.
df <- data.frame(a.1 = runif(5), b.1 = runif(5), a.2 = runif(5), b.2 = runif(5))
df$repetition = c(1:nrow(df))
library(reshape2)
tmp = melt(df, id.vars = "repetition")
names(tmp)[2] = "condition"
tmp$treatment = substring(tmp$condition,1,1)
這樣產生:
> head(tmp)
repetition condition value treatment
1 1 a.1 0.6668952 a
2 2 a.1 0.1248151 a
3 3 a.1 0.7082199 a
4 4 a.1 0.9840956 a
5 5 a.1 0.4479190 a
6 1 b.1 0.9381539 b
現在,剩下的事情很容易了,我們依靠流行的plyr軟件包:
library(plyr)
results = ddply(tmp, .(repetition, treatment), summarize, mean = mean(value), sd = sd(value) )
最終結果是
> head(results)
repetition treatment mean sd
1 1 a 0.6777342 0.01532853
2 1 b 0.6734955 0.37428353
3 2 a 0.4533126 0.46456561
4 2 b 0.8441925 0.07260509
5 3 a 0.3967338 0.44050779
6 3 b 0.5886821 0.42635902
希望這就是您想要的。
如果您不想區分每個重復,而是在治療水平上,則還有一個更有趣的補充
# addition
results = ddply(tmp, .( treatment), summarize, mean = mean(value), sd = sd(value) )
結果:
> head(results)
treatment mean sd
1 a 0.5817867 0.2954151
2 b 0.6212537 0.3219035
使用tidyr
和tidyr
的管道運算符, magrittr
將數據鞭打成形狀的“僅基礎”要求:
set.seed(42)
df <- data.frame(a.1 = runif(5), b.1 = runif(5), a.2 = runif(5), b.2 = runif(5))
df2 <- df %>%
gather(treatment, value) %>%
separate(treatment, c("treatment", "repetition"))
head(df2)
# treatment repetition value
# 1 a 1 0.13871017
# 2 a 1 0.98889173
# 3 a 1 0.94666823
# 4 a 1 0.08243756
# 5 a 1 0.51421178
# 6 b 1 0.39020347
現在,我不確定您要獲取的平均值和標准偏差到底是什么,但是一個簡單的選擇是從基數R的aggregate()
。簡單地通過FUN
參數傳遞所需的函數:
# calculate mean on treatment (a or b)
aggregate(df2$value, by = list(treatment = df2$treatment), FUN = mean)
# treatment repetition x
# 1 a 1 0.5341839
# 2 b 1 0.6633022
# 3 a 2 0.5442395
# 4 b 2 0.4225865
# calculate mean on treatment and repetition
aggregate(df2$value, by = list(treatment = df2$treatment, repetition = df2$repetition, FUN = mean)
# treatment x
# 1 a 0.5392117
# 2 b 0.5429444
根據您顯示的代碼,這種base R
方法可能會有所幫助:
set.seed(42)
df <- data.frame(a.1 = runif(5), b.1 = runif(5), a.2 = runif(5), b.2 = runif(5))
do.call(cbind,
lapply(split(seq_along(df),gsub("\\..*", "",colnames(df))), function(x) {
x1 <- df[,x]
data.frame(Means=rowMeans(x1, na.rm=TRUE), SD=apply(x1, 1, sd, na.rm=TRUE))}))
# a.Means a.SD b.Means b.SD
#1 0.6862739 0.3231932 0.7295552 0.29763438
#2 0.8280938 0.1541232 0.8574074 0.17086395
#3 0.6104059 0.4585819 0.1260770 0.01214755
#4 0.5429382 0.4065997 0.5659947 0.12869005
#5 0.5520192 0.1268922 0.6326988 0.10234101
使用您的代碼,我得到相同的結果
vec1 <- vector("numeric", length=5)
for(i in c("a.1", "a.2")) {vec1 <- vec1+df[[i]]}
vec1/2
#[1] 0.6862739 0.8280938 0.6104059 0.5429382 0.5520192
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.