R:将对象附加到数组:为什么不保留数据结构?

时间:2018-02-05 09:34:01

标签: r list vector append

当我将一个对象追加到一个向量或列表时,附加对象的结构会以某种方式混淆。在我的情况下,我想附加predict()模型的glm()结果,该模型本身就是命名列表according to the docs):

  

如果是se.fit = TRUE,则是包含组件的列表

     

fit:预测,与se.fit = FALSE一样。

     

se.fit:估计的标准错误。

     

residual.scale:一个标量,给出计算中使用的色散的平方根   标准错误。

示例设置:

dat <- data.frame(x=c(1,2,3,4,5), param=c(1,2,1,2,1), y=c(3,6,5,8,8))
mdl <- glm(y ~ x + param, data=dat)
lvls <- c(1,2)
x <- seq(1,5, length.out=10)

我尝试了几种方法

# 1st approach
pred1 <- c()
for(i in 1:length(lvls)) {
    prd <- predict(mdl, data.frame(x=x, param=lvls[i]), se.fit=TRUE)
    pred1 <- c(pred1, prd)
}    
print(attributes(prd))  # this returns what I expect
# $names
# [1] "fit"            "se.fit"         "residual.scale"
print(attributes(pred1[1]))
# $names
# [1] "fit"



# 2nd approach
pred2 <- list()
for(i in 1:length(lvls)) {
    prd <- predict(mdl, data.frame(x=x, param=lvls[i]), se.fit=TRUE)
    pred2[i] <- prd  # this raises an error 
}



# 3rd approach
pred3 <- list()
for(i in 1:length(lvls)) {
    prd <- predict(mdl, data.frame(x=x, param=lvls[i]), se.fit=TRUE)
    pred3 <- append(pred3, prd)
}
print(attributes(pred3[1]))
# $names
# [1] "fit"

如您所见,只有第一个命名属性$fit保留在向量或列表中。我无法像我期望的那样访问$se.fit

pred3[1]$se.fit  # I would expect to be able to do this for the first prediction
# NULL

相反,似乎原始对象的所有命名属性都被展平为一个序列,每个项目都有一个属性

pred3[1]
# $fit
#        1        2        3        4        5        6        7        8        9       10 
# 2.933333 3.466667 4.000000 4.533333 5.066667 5.600000 6.133333 6.666667 7.200000 7.733333 

pred3[2]
# $se.fit
#         1         2         3         4         5         6         7         8         9        10 
# 0.3126944 0.2769618 0.2467901 0.2244334 0.2123744 0.2123744 0.2244334 0.2467901 0.2769618 0.3126944 

pred3[3]
# $residual.scale
# [1] 0.3651484

pred3[4]
# $fit
#        1        2        3        4        5        6        7        8        9       10 
# 4.600000 5.133333 5.666667 6.200000 6.733333 7.266667 7.800000 8.333333 8.866667 9.400000 

pred3[5]
# $se.fit
#         1         2         3         4         5         6         7         8         9        10 
# 0.3464102 0.3145315 0.2883185 0.2694301 0.2594708 0.2594708 0.2694301 0.2883185 0.3145315 0.3464102 

pred3[6]
# $residual.scale
# [1] 0.3651484
  1. 为什么会这样?
  2. 如何按原样附加对象&#39;

2 个答案:

答案 0 :(得分:0)

这个怎么样

library('magrittr')
pred1 <- c()
for(i in 1:length(lvls)) {
  prd <- predict(mdl, data.frame(x=x, param=lvls[i]), se.fit=TRUE)
  pred1 %<>% append(prd)
}

答案 1 :(得分:0)

我找到了答案。我刚发现双括号索引@Inject

This thread解释了差异。至关重要的是:

  

对于列表,通常使用//Base Address for StudentService Uri httpBaseAddress = new Uri("http://localhost:0000/Service1"); //Instantiate ServiceHost ServiceHost svcHost = new ServiceHost(typeof(Service1), httpBaseAddress); //Add Endpoint to Host svcHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), ""); //Open svcHost.Open(); 来选择任何单个元素,而[[返回所选元素的列表。

我已经玩过这个并找到了解决方案:

[[

我也明白为什么我的第一种方法不起作用。解释是here[

  

提取或替换对象的部分

     

描述

     

操作符作用于矢量,矩阵,数组和列表以提取或替换部件。   使用

# 4th approach - like 2nd but [[ instead [
pred4 <- list()
for(i in 1:length(lvls)) {
    prd <- predict(mdl, data.frame(x=x, param=lvls[i]), se.fit=TRUE)
    pred4[[i]] <- prd
}


pred4[[1]]$fit
#        1        2        3        4        5        6        7        8        9       10 
# 2.933333 3.466667 4.000000 4.533333 5.066667 5.600000 6.133333 6.666667 7.200000 7.733333 

pred4[[1]]$se.fit
#         1         2         3         4         5         6         7         8         9        10 
# 0.3126944 0.2769618 0.2467901 0.2244334 0.2123744 0.2123744 0.2244334 0.2467901 0.2769618 0.3126944 

pred4[[1]]$residual.scale
# [1] 0.3651484

因此?Extract - 结果列表的命名条目位于同一级别或索引维度,其中向量执行其追加操作。 提取/索引方法是等效的。这意味着x[i] x[i, j, ... , drop = TRUE] x[[i, exact = TRUE]] x[[i, j, ..., exact = TRUE]] x$name getElement(object, name) 只是predict的别名。因此,对于单括号,我不附加元素,而是将3个命名元素的列表添加到另一个。