如何在数据框列表中添加具有特定值的列

时间:2017-08-02 09:18:52

标签: r list dataframe

我一直在寻找一个简单的代码来从网上抓取数据。结果是列表中的数据帧列表。我想要做的是为每个数据帧添加特定的信息,以便之后绑定它们。

这是代码

page_numbers <- c(123, 124, 125, 126)

urls <- paste("http://www.abstimmungen.bl.ch/de/vote/detail/", page_numbers, sep = "")

Data <- lapply(urls, function(x){readHTMLTable(getURL(x),stringsAsFactors=F)})

没有什么可以让我区分不同的数据帧。因此,我认为要列出名称如下

Title <- list("Bruderholz-Initiative", "Lehrpersonen-Initiative", "Abschaffung Amtszeitbeschränkung", "Aufgabenzuordnung BL-Gemeinden")

我想将相同的列变量添加到名为Title的所有数据框中,并使用循环为每个数据框添加特定值。

for( i in Data){
  Data[[i]]$Titre <- rep(Titre[i],
                         nrow(as.data.frame(Data[[i]]))
                         )}

由于不正确的指示,结果是错误。 或者,我已经尝试了另一段代码

Data2 <- Map(transform , Data, Titres = Titre[i])

我真的不知道如何纠正我的代码以使其有效,我只能猜测我的列表结构会导致问题。任何帮助都非常受欢迎 提前谢谢!

2 个答案:

答案 0 :(得分:1)

OP的目标是为每个数据帧添加特定信息,以便之后绑定它们。

OP提供的样本数据表明,只有一个项目Title应该添加,大概是为了以后的分组。如果是这种情况,那么使用rindlist()包中的data.table就可以得到一个简单的解决方案,该包在绑定时“命名”行:

# remove one list level to get a list of data.frames
# (as already suggested by the OP)
Data1 <- unlist(Data, recursive = FALSE)
# name the list elements
Data1 <- setNames(Data1, Title)
str(Data1)
List of 4
 $ Bruderholz-Initiative           :'data.frame': 91 obs. of  9 variables:
  ..$ Bezirk   : chr [1:91] "Bezirk Arlesheim" "Aesch" "Allschwil" "Arlesheim" ...
  ..$ Resultat : chr [1:91] "abgelehnt11680" "abgelehnt" "abgelehnt" "abgelehnt" ...
  ..$ Ja       : chr [1:91] "15433" "840" "1473" "727" ...
  ..$ Nein     : chr [1:91] "27159" "1606" "3513" "1982" ...
  ..$ Leer     : chr [1:91] "864" "38" "121" "75" ...
  ..$ Ungültig: chr [1:91] "758" "18" "179" "59" ...
  ..$ Ja%      : chr [1:91] "36.23" "34.34" "29.54" "26.84" ...
  ..$ Nein%    : chr [1:91] "63.77" "65.66" "70.46" "73.16" ...
  ..$ Gemeldet : chr [1:91] "15 von 15" "ja" "ja" "ja" ...
 $ Lehrpersonen-Initiative         :'data.frame': 91 obs. of  9 variables:
[...]
 $ Abschaffung Amtszeitbeschränkung:'data.frame': 91 obs. of  9 variables:
[...]
 $ Aufgabenzuordnung BL-Gemeinden  :'data.frame': 91 obs. of  9 variables:
[...]
library(data.table)
# combine all rows, thereby creating an id column Title containing 
# the names of the list elements 
DT <- rbindlist(Data1, idcol = "Title")
DT 
                              Title           Bezirk       Resultat    Ja  Nein Leer Ungültig   Ja% Nein%  Gemeldet
  1:          Bruderholz-Initiative Bezirk Arlesheim abgelehnt11680 15433 27159  864       758 36.23 63.77 15 von 15
  2:          Bruderholz-Initiative            Aesch      abgelehnt   840  1606   38        18 34.34 65.66        ja
  3:          Bruderholz-Initiative        Allschwil      abgelehnt  1473  3513  121       179 29.54 70.46        ja
  4:          Bruderholz-Initiative        Arlesheim      abgelehnt   727  1982   75        59 26.84 73.16        ja
  5:          Bruderholz-Initiative      Biel-Benken      abgelehnt   565   575   23        20 49.56 50.44        ja
 ---                                                                                                                
360: Aufgabenzuordnung BL-Gemeinden       Niederdorf     angenommen   298    85   15         4 77.81 22.19        ja
361: Aufgabenzuordnung BL-Gemeinden         Oberdorf     angenommen   416   119   27         4 77.76 22.24        ja
362: Aufgabenzuordnung BL-Gemeinden      Reigoldswil     angenommen   333    65   23         7 83.67 16.33        ja
363: Aufgabenzuordnung BL-Gemeinden        Titterten     angenommen   122    28    9         4 81.33 18.67        ja
364: Aufgabenzuordnung BL-Gemeinden       Waldenburg     angenommen   158    45   23         4 77.83 22.17        ja

为了完整起见,还有其他方法可以在绑定之前将id列添加到单个数据行

在原始的嵌套列表中:

Data0 <- lapply(seq_along(Data), function(.i) cbind(Data[[.i]][[1]], Title = Title[[.i]]))
str(Data0[1])
List of 1
 $ :'data.frame': 91 obs. of  10 variables:
  ..$ Bezirk   : chr [1:91] "Bezirk Arlesheim" "Aesch" "Allschwil" "Arlesheim" ...
  ..$ Resultat : chr [1:91] "abgelehnt11680" "abgelehnt" "abgelehnt" "abgelehnt" ...
  ..$ Ja       : chr [1:91] "15433" "840" "1473" "727" ...
  ..$ Nein     : chr [1:91] "27159" "1606" "3513" "1982" ...
  ..$ Leer     : chr [1:91] "864" "38" "121" "75" ...
  ..$ Ungültig: chr [1:91] "758" "18" "179" "59" ...
  ..$ Ja%      : chr [1:91] "36.23" "34.34" "29.54" "26.84" ...
  ..$ Nein%    : chr [1:91] "63.77" "65.66" "70.46" "73.16" ...
  ..$ Gemeldet : chr [1:91] "15 von 15" "ja" "ja" "ja" ...
  ..$ Title    : Factor w/ 1 level "Bruderholz-Initiative": 1 1 1 1 1 1 1 1 1 1 ...

或在“扁平”列表中:

Data1 <- unlist(Data, recursive = FALSE)
Data2 <- lapply(seq_along(Data1), function(.i) cbind(Data1[[.i]], Title = Title[[.i]]))
str(Data2[1])
List of 1
 $ :'data.frame': 91 obs. of  10 variables:
  ..$ Bezirk   : chr [1:91] "Bezirk Arlesheim" "Aesch" "Allschwil" "Arlesheim" ...
  ..$ Resultat : chr [1:91] "abgelehnt11680" "abgelehnt" "abgelehnt" "abgelehnt" ...
  ..$ Ja       : chr [1:91] "15433" "840" "1473" "727" ...
  ..$ Nein     : chr [1:91] "27159" "1606" "3513" "1982" ...
  ..$ Leer     : chr [1:91] "864" "38" "121" "75" ...
  ..$ Ungültig: chr [1:91] "758" "18" "179" "59" ...
  ..$ Ja%      : chr [1:91] "36.23" "34.34" "29.54" "26.84" ...
  ..$ Nein%    : chr [1:91] "63.77" "65.66" "70.46" "73.16" ...
  ..$ Gemeldet : chr [1:91] "15 von 15" "ja" "ja" "ja" ...
  ..$ Title    : Factor w/ 1 level "Bruderholz-Initiative": 1 1 1 1 1 1 1 1 1 1 ...

没有类型的for循环来完成任务。

请注意,默认情况下,cbind()已将Title设置为系数。可以通过在stringsAsFactors = FALSE的调用中包含参数cbind()来关闭此功能。

这两种方法都返回一个data.frames列表,可以按行

直接组合
do.call(rbind, Data0)

rbindlist(Data0)

答案 1 :(得分:1)

为了避免以后添加 Title 的问题,为什么不在我们逐个读取url时在apply循环中添加 Title ,然后rbind,请参阅:

library(XML)
library(RCurl)

page_numbers <- c(123, 124, 125, 126)
Title <- c("Bruderholz-Initiative", "Lehrpersonen-Initiative",
           "Abschaffung Amtszeitbeschränkung", "Aufgabenzuordnung BL-Gemeinden")

Data <- 
  do.call(rbind,
          lapply(seq(page_numbers),
                 function(x){
                   myURL <- paste("http://www.abstimmungen.bl.ch/de/vote/detail/", page_numbers[x], sep = "")
                   # above is returning a list, so take the first one...
                   dd <- readHTMLTable(getURL(myURL), stringsAsFactors = FALSE)[[1]]
                   dd$Title <- Title[x]
                   # return
                   dd
                 })
  )