如何将数据添加到R数据框

时间:2014-07-30 10:09:23

标签: r

我无法想象它应该是那么困难,但可能来自Python,我的心态有偏见。

我知道我要进行50次计算,每次计算的结果以及表征计算的两个参数都应该建立一个数据框。

所以我的方法是实例化数据框,然后我想在结果可用时添加结果。请参阅下面的指示行:

# Number of simulations
nsim = 50

# The data frame which should carry the calculation (parameters and solutions).
sol <- data.frame(col.names=c("ni", "Xbar", "n"))

# Fifty values for n.
n <- seq.int(5, 5000, length.out=nsim)

for(ni in n)
{
    # A random sample containing possible duplicates.
    X <- sample(seq(-ni, ni, length=ni+1), replace=T)
    Xbar <- round(mean(X), 3)
    sol <- rbind(sol, c(ni, Xbar, n))  # <<-- How to do this correctly??
}   

这不起作用。

3 个答案:

答案 0 :(得分:2)

有两种方法可以正确执行此操作。一种是预先定义你的data.frame(它的大小),然后在for循环中迭代填充它:

nsim <- 10 # reduce to 10 to simplify output
n <- seq.int(5, 5000, length.out=nsim)

sol <- setNames(data.frame(matrix(nrow=nsim, ncol=3)), c("ni", "Xbar", "n"))

set.seed(1) # for reproducibility
for(ni in seq_along(n)) {
    Xbar <- round(mean(sample(seq(-n[ni], n[ni], length=n[ni]+1), replace=T)), 3)
    sol[ni,] <- c(ni, Xbar, n[ni])
}   

或者,您可以在sapply向量上使用n创建结果向量,然后将cbind所有内容重新组合在一起:

set.seed(1) # for reproducibility
sol <- data.frame(
    ni = seq_along(n),
    Xbar = sapply(n, function(ni) {
        round(mean(sample(seq(-ni, ni, length=ni+1), replace=T)), 3)
    }),
    n = n
)

无论哪种方式,您都会得到一个不错的数据框:

> str(sol)
'data.frame':   10 obs. of  3 variables:
 $ ni  : num  1 2 3 4 5 6 7 8 9 10
 $ Xbar: num  0.667 -0.232 -14.599 -26.026 36.51 ...
 $ n   : num  5 560 1115 1670 2225 ...

答案 1 :(得分:1)

1)检查您的初始sol包含的内容。

> sol <- data.frame(col.names=c("ni", "Xbar", "n"))
> sol
  col.names
1        ni
2      Xbar
3         n

不是你想要的。请参阅this question

2)确保seq.int符合您的期望 - 查看seq.int的文档(或仅输出)。n。例如看看> n [1] 5.0000 106.9388 208.8776 310.8163 412.7551 514.6939 616.6327 [8] 718.5714 820.5102 922.4490 1024.3878 1126.3265 1228.2653 1330.2041 [15] 1432.1429 1534.0816 1636.0204 1737.9592 1839.8980 1941.8367 2043.7755 [22] 2145.7143 2247.6531 2349.5918 2451.5306 2553.4694 2655.4082 2757.3469 [29] 2859.2857 2961.2245 3063.1633 3165.1020 3267.0408 3368.9796 3470.9184 [36] 3572.8571 3674.7959 3776.7347 3878.6735 3980.6122 4082.5510 4184.4898 [43] 4286.4286 4388.3673 4490.3061 4592.2449 4694.1837 4796.1224 4898.0612 [50] 5000.0000 包含的内容:

sim = 50
sol <- data.frame(col.names=c("ni", "Xbar", "n"))
ni=5
X <- sample(seq(-ni, ni, length=ni+1), replace=T)
Xbar <- round(mean(X), 3)
sol <- rbind(sol, c(ni, Xbar, n))  
print(sol)

这是你的意思吗?

3)给定(1)问题并不令人惊讶,但无论如何,只要第一次通过循环执行一次一行。看看会发生什么:

Warning message:
In `[<-.factor`(`*tmp*`, ri, value = 5) :
  invalid factor level, NA generated
>     print(sol)
  col.names
1        ni
2      Xbar
3         n
4      <NA>

给出:

sol

现在这种行为并不令人惊讶;我们无法在一列中添加三列。

4)无论如何,你不想这样做。最好将{{1}}初始化为最终大小,然后将其填入。

例如,请参阅this answer

然而,更常见的R习惯用法是尽可能避免循环;有许多功能可以让你一次创建整个东西。

答案 2 :(得分:0)

首先,您能否澄清您期望的预期输出格式? 截至目前,在修改代码以生成数据框时,将生成以下输出(让我知道这是否是您所期望的,然后生成以下内容并不困难):

ni       Xbar     n
10.000   2.182   12.000

如果这是你所期望的,那么一种方法是:

第1步:创建向量

步骤2:从上面的向量中创建数据框

第3步:在循环中运行您的操作&amp;逐行填写。

nsim=50
n=seq.int(5, 5000, length.out=nsim)
ni<-vector(mode='numeric',length=nsim)
Xbar<-vector(mode='numeric',length=nsim)
out<-data.frame(ni=ni,Xbar=Xbar,n=n)

for ( i in 1:length(n)){
  X<- sample(seq(-n[i], n[i], length=n[i]+1), replace=T)
  out[i,'Xbar'] <- round(mean(X), 3)
  out[i,'ni']<-n[i]
}

输出如下:

enter image description here