将 do() 与列表元素的名称一起使用
Posted
技术标签:
【中文标题】将 do() 与列表元素的名称一起使用【英文标题】:Using do() with names of list elements 【发布时间】:2016-05-22 12:17:49 【问题描述】:我正在尝试获取列表元素的名称并使用 do() 对所有元素应用函数,然后将它们绑定到单个数据框中。
require(XML)
require(magrittr)
url <- "http://gd2.mlb.com/components/game/mlb/year_2016/month_05/day_21/gid_2016_05_21_milmlb_nynmlb_1/boxscore.xml"
box <- xmlParse(url)
xml_data <- xmlToList(box)
end <- length(xml_data[[2]]) - 1
x <- seq(1:end)
away_pitchers_names <- paste0("xml_data[[2]][", x, "]")
away_pitchers_names <- as.data.frame(away_pitchers_names)
names(away_pitchers_names) <- "elements"
away_pitchers_names$elements %<>% as.character()
listTodf <- function(x)
df <- as.data.frame(x)
tdf <- as.data.frame(t(df))
row.names(tdf) <- NULL
tdf
test <- away_pitchers_names %>% group_by(elements) %>% do(listTodf(.$elements))
当我在列表元素上运行 listTodf
函数时,它工作正常:
listTodf(xml_data[[2]][1]
id name name_display_first_last pos out bf er r h so hr bb np s w l sv bs hld s_ip s_h s_r s_er s_bb
1 605200 Davies Zach Davies P 16 22 4 4 5 5 2 2 86 51 1 3 0 0 0 36.0 41 24 23 15
s_so game_score era
1 25 45 5.75
但是当我尝试使用 do() 函数遍历元素的名称时,我得到以下信息:
Warning message:
In rbind_all(out[[1]]) : Unequal factor levels: coercing to character
这是输出:
> test
Source: local data frame [5 x 2]
Groups: elements [5]
elements V1
(chr) (chr)
1 xml_data[[2]][1] xml_data[[2]][1]
2 xml_data[[2]][2] xml_data[[2]][2]
3 xml_data[[2]][3] xml_data[[2]][3]
4 xml_data[[2]][4] xml_data[[2]][4]
5 xml_data[[2]][5] xml_data[[2]][5]
我确信这是非常简单的事情,但我不知道哪里出了问题。
【问题讨论】:
你能解释一下为什么你用同一个分组变量转置分组变量,然后将整个东西组合成一个data.frame吗?请详细说明你究竟想用minimal reproducible example做些什么 列表的每个元素都有相同的变量,它们只是代表不同的情况。因此,我尝试将每个元素组合在一起,然后以宽格式显示它们(因为将列表元素转换为数据框以长格式显示)。 如果您正在评估字符串,请使用eval(parse(..
即lapply(away_pitchers_names$elements, function(x) listTodf(eval(parse(text=x))))
另外,请注意在listTodf
函数中,as.data.frame
是在没有stringsAsFactors=FALSE
的情况下调用的,因此所有字符列都会默认为 factor
类,这将导致您帖子中提到的警告。
【参考方案1】:
为了评估字符串,可以使用eval(parse
library(dplyr)
lapply(away_pitchers_names$elements,
function(x) as.data.frame.list(eval(parse(text=x))[[1]], stringsAsFactors=FALSE)) %>%
bind_rows()
# id name name_display_first_last pos out bf er r h so hr bb np s w l
#1 605200 Davies Zach Davies P 16 22 4 4 5 5 2 2 86 51 1 3
#2 430641 Boyer Blaine Boyer P 2 4 0 0 2 0 0 0 8 7 1 0
#3 448614 Torres, C Carlos Torres P 3 4 0 0 0 1 0 2 21 11 0 1
#4 592804 Thornburg Tyler Thornburg P 3 3 0 0 0 1 0 0 14 8 2 1
#5 518468 Blazek Michael Blazek P 1 5 1 1 2 0 0 2 23 10 1 1
# sv bs hld s_ip s_h s_r s_er s_bb s_so game_score era loss note
#1 0 0 0 36.0 41 24 23 15 25 45 5.75 <NA> <NA>
#2 0 1 0 21.1 22 4 4 5 7 48 1.69 <NA> <NA>
#3 0 0 2 22.1 22 9 9 14 21 52 3.63 <NA> <NA>
#4 1 2 8 18.2 13 8 8 7 29 54 3.86 <NA> <NA>
#5 0 1 8 21.1 23 6 6 14 18 41 2.53 true (L, 1-1)
但是,这样做更容易,更快捷
lapply(xml_data[[2]][1:5], function(x)
as.data.frame.list(x, stringsAsFactors=FALSE)) %>%
bind_rows()
【讨论】:
这正是我想要的。想错了方向。谢谢!以上是关于将 do() 与列表元素的名称一起使用的主要内容,如果未能解决你的问题,请参考以下文章
将 .index() 与具有重复元素的列表一起使用 [重复]
将 BootstrapVue 与 Vue.Draggable 一起使用?并将项目从列表中删除到 b 表?
如何将展开和折叠列表行与 Core Data 元素一起使用?