循环通过R数据帧的行为不符合预期。为什么呢?

时间:2017-07-21 04:32:57

标签: r

我的目标是逐行循环R数据帧。我知道你可以通过索引在循环之外做,就像我想要我的数据帧df的第1到第5行,我只是做df [1:5,],这给了我1:5行的每一列我的数据框。但是我经常不确切地知道我想要哪些行,但是我想在for循环中逐行遍历我的数据帧,这样我就可以应用"如果"条件,并将行读入列表,并匹配匹配。我还没有弄明白我的问题的每一步,但我想知道为什么这个for循环不会像我预期的那样表现,我希望它会。

所以我正在使用内置的R数据集" CO2"。 所以它看起来像是84行和5列:

> CO2[1:10,]
   Plant   Type  Treatment conc uptake
1    Qn1 Quebec nonchilled   95   16.0
2    Qn1 Quebec nonchilled  175   30.4
3    Qn1 Quebec nonchilled  250   34.8
4    Qn1 Quebec nonchilled  350   37.2
5    Qn1 Quebec nonchilled  500   35.3
6    Qn1 Quebec nonchilled  675   39.2
7    Qn1 Quebec nonchilled 1000   39.7
8    Qn2 Quebec nonchilled   95   13.6
9    Qn2 Quebec nonchilled  175   27.3
10   Qn2 Quebec nonchilled  250   37.1

这是我迄今为止所取得的成就。

   for(i in 1:nrow(CO2)) # "i" is incrementer from 1 to 84.
    {
        r <- CO2[i,] # r is our current row. 
        if(r$conc == 95 & r$Treatment == "nonchilled"){print(r)} 

    }

所以这就是我从那段代码中得到的。

 Plant   Type  Treatment conc uptake
1   Qn1 Quebec nonchilled   95     16
  Plant   Type  Treatment conc uptake
8   Qn2 Quebec nonchilled   95   13.6
   Plant   Type  Treatment conc uptake
15   Qn3 Quebec nonchilled   95   16.2
   Plant        Type  Treatment conc uptake
43   Mn1 Mississippi nonchilled   95   10.6
   Plant        Type  Treatment conc uptake
50   Mn2 Mississippi nonchilled   95     12
   Plant        Type  Treatment conc uptake
57   Mn3 Mississippi nonchilled   95   11.3

非常酷。但是,我不希望它复制标题,那么如何在不使用子集函数的情况下修改我的代码以在for循环中生成此结果?所以我希望输出看起来像这样:

 Plant        Type  Treatment conc uptake
1    Qn1      Quebec nonchilled   95   16.0
8    Qn2      Quebec nonchilled   95   13.6
15   Qn3      Quebec nonchilled   95   16.2
43   Mn1 Mississippi nonchilled   95   10.6
50   Mn2 Mississippi nonchilled   95   12.0
57   Mn3 Mississippi nonchilled   95   11.3

正如您所看到的,标题只出现一次。是的,子集函数功能强大,但它可以使我无法逐行迭代遍历数据帧。

另外,我觉得有趣的是,我的for循环给了我一个行数,其中浓度都是95,治疗是&#34;非冷却&#34;同时。那我怎么能在for循环中隔离那些呢?

嘿,我想出了什么。我意识到R正在解释变量&#34; r&#34;作为包含所有列和1行的数据框架。因此,如果内部if条件,我从&#34; r&#34;删除列名称在那里,我得到的结果看起来很漂亮,有行号,但遗憾的是没有标题。

for(i in 1:nrow(CO2)) # "i" is incrementer from 1 to 84.
{
    r <- CO2[i,] # r is our current row. 
    if(r$conc == 95 & r$Treatment == "nonchilled"){
        names(r) = NULL; # Removes headers. # It's important to do it here specifically.
        print(r)} 
}

所以它产生了这个:

 1 Qn1 Quebec nonchilled 95 16

8 Qn2 Quebec nonchilled 95 13.6

15 Qn3 Quebec nonchilled 95 16.2

43 Mn1 Mississippi nonchilled 95 10.6

50 Mn2 Mississippi nonchilled 95 12

57 Mn3 Mississippi nonchilled 95 11.3

2 个答案:

答案 0 :(得分:1)

这是一个有效的代码。但标题未对齐。

df <- mtcars
print(paste(colnames(df)))
for (i in seq(1,10)){
    r <- paste(df[i,])  
  print(r)
} 

但是,我不确定这是否对您的最终目标非常有帮助。您可以尝试发布具有最终意图的新问题。一般来说,R对于几乎所有由循环完成的事情都有替代的,更好的选择。

答案 1 :(得分:1)

这适合你吗?

df<-data.frame(Plant=character(0), Type=character(0), 
                Treatment=character(0), conc=numeric(0), 
                uptake=numeric(0))

for(i in 1:nrow(CO2)){if(CO2$conc[i]==95 & CO2$Treatment[i]=="nonchilled"){
df<-rbind(df,CO2[i,])}}
> df
#    Plant        Type  Treatment conc uptake
#1    Qn1      Quebec nonchilled   95   16.0
#8    Qn2      Quebec nonchilled   95   13.6
#15   Qn3      Quebec nonchilled   95   16.2
#43   Mn1 Mississippi nonchilled   95   10.6
#50   Mn2 Mississippi nonchilled   95   12.0
#57   Mn3 Mississippi nonchilled   95   11.3