【问题标题】:How to put values inside a column based on other column values in R如何根据R中的其他列值将值放入列中
【发布时间】:2018-11-30 04:43:36
【问题描述】:

我正在与 R 合作,为我作为记者的工作抓取和清理数据。我可以获取 HTML 表格,然后将其作为数据框读取并重命名列的名称。现在我正在尝试创建一个新列,该列会考虑其他列的值来获取值。

这个新列应该获得“Avante”、“DEM”、“MDB”、“Patriota”、“PCdoB”等值。这是每个代表的党。例如,Avante 有三名副手,分别是“Adalberto Cavalcanti”、“Cabo Sabino”和“Silvio Costa”。代表的名字总是排在党名的下方。

url <- "http://www.camara.leg.br/internet/votacao/mostraVotacao.asp?ideVotacao=8559&numLegislatura=55&codCasa=1&numSessaoLegislativa=4&indTipoSessaoLegislativa=O&numSessao=225&indTipoSessao=E&tipo=partido"

library(xml2)
library(rvest)
file <- read_html(url)
tables <- html_nodes(file, "table")
table1 <- html_table(tables[3], fill = TRUE, header = T)

head(table1)

table1_df <- as.data.frame(table1)

colnames(table1_df) <- c("deputado", "uf", "voto")

这就是我现在拥有的: enter image description here

这就是我想要的: enter image description here

【问题讨论】:

  • 不清楚你想要什么。你能显示几行预期的输出吗
  • 好的,我刚刚添加了我所拥有的以及我正在尝试做的事情的图片。

标签: r dplyr tidyverse rvest data-cleaning


【解决方案1】:

这是一个仅使用基础 R 的解决方案:

url <- "http://www.camara.leg.br/internet/votacao/mostraVotacao.asp?ideVotacao=8559&numLegislatura=55&codCasa=1&numSessaoLegislativa=4&indTipoSessaoLegislativa=O&numSessao=225&indTipoSessao=E&tipo=partido"

library(xml2)
library(rvest)
file <- read_html(url)
tables <- html_nodes(file, "table")
table1 <- html_table(tables[3], fill = TRUE, header = T)

head(table1)

table1_df <- as.data.frame(table1)

colnames(table1_df) <- c("deputado", "uf", "voto")

# create the new column for later
table1_df$new_column <- NA

# identify rows with the Total PARTY: NUM rows
idx <- grep("Total.*: \\d+", table1_df$deputado)

# Loop over these and assign the values
for (i in seq_along(idx)){
  # Extract the number of deputados
  n <- as.numeric(sub("^.*: ", "", table1_df$deputado[idx[i]]))
  # Extract the party
  partido <- sub("Total ", "", table1_df$deputado[idx[i]])
  partido <- sub(": .*", "", partido)
  # Assign the values
  table1_df$new_column[(idx[i] - n):(idx[i] - 1)] <- partido
}

# Remove the unnecessary lines
table1_df <- table1_df[-grep("Total .*:.*", table1_df$deputado), ]
table1_df <- table1_df[-which(table1_df$deputado == table1_df$uf), ]

【讨论】:

    【解决方案2】:

    这是另一个使用 zoodplyr 的选项。

    1) 获取各方名称。

    parties <- sub(pattern = "Total\\s(.+):\\s\\d+", 
                    replacement = "\\1", 
                    x = table1_df$deputado[grepl("Total", x = table1_df$deputado)])
    

    2) 将parties 添加为新列并携带最后的观察结果,因为parties[match(table1_df$deputado, parties)] 中有很多NAs。

    table1_df$new_col <- zoo::na.locf(parties[match(table1_df$deputado, parties)])
    

    3) 删除不需要的行。

    library(dplyr)
    table1_df <- table1_df %>% 
      group_by(new_col) %>% 
      slice(2:(n()-1))
    table1_df
    # A tibble: 324 x 4
    # Groups:   new_col [24]
    #   deputado             uf    voto      new_col
    #   <chr>                <chr> <chr>     <chr>  
    # 1 Adalberto Cavalcanti PE    Não       Avante 
    # 2 Cabo Sabino          CE    Abstenção Avante 
    # 3 Silvio Costa         PE    Sim       Avante 
    # 4 Alan Rick            AC    Sim       DEM    
    # 5 Alberto Fraga        DF    Não       DEM    
    # 6 Alexandre Leite      SP    Sim       DEM    
    # 7 Arthur Oliveira Maia BA    Sim       DEM    
    # 8 Carlos Melles        MG    Sim       DEM    
    # 9 Efraim Filho         PB    Não       DEM    
    #10 Eli Corrêa Filho     SP    Sim       DEM    
    # ... with 314 more rows
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多