下面的代码段将一对向量转换为数据帧,并沿一列填充以指示出处(“状态”),另一列填充以指示类型(“成分”)。
overflow <- setdiff(c(21, 23, 27), c(21, 23))
underflow <- setdiff(c(11, 13, 17), c(17))
dfo <- data.frame("State"="over", Value=overflow)
dfu <- data.frame("State"="under", Value=underflow)
df <- rbind(dfo, dfu)
df$Ingredient <- "Beans"
使用给定的数据,一切都很好。我们得到以下数据框。
> df
State Value Ingredient
1 over 27 Beans
2 under 11 Beans
3 under 13 Beans
但是对于setdiff
产生空向量(例如:underflow <- setdiff(c(11, 13, 17), c(11, 13, 17))
)的边界情况,这还不够好。
在处理空向量的情况下,如何从向量构建数据帧?带有“数据框为空”标志的选项将是一个不好的选择,因为该代码将充满if
语句。
更新
代替对@AndS。的建议的评论:
用data.frame
替换dplyr::data_frame
效果很好。最初至少。但是插入列仍然是有问题的。如果overflow
和underflow
均为空列表,则df$Ingredient <- "Beans"
失败。
答案 0 :(得分:1)
使用dplyr::data_frame
可能是最好的选择,但这是一个有趣的基本R方法
flow <- list(over = setdiff(c(21, 23, 27), c(21, 23)),
under = setdiff(c(11, 13, 17), c(17)))
flow.df <- Map(function(State, x)
if(length(x)) data.frame(State, x, Ingredient = 'Beans')
, names(flow)
, flow)
df <- do.call(rbind, flow.df)
df
# State x Ingredient
# over over 27 Beans
# under.1 under 11 Beans
# under.2 under 13 Beans
其中一个为空时:
flow <- list(over = setdiff(c(21, 23, 21), c(21, 23)),
under = setdiff(c(11, 13, 17), c(17)))
flow.df <- Map(function(State, x)
if(length(x)) data.frame(State, x, Ingredient = 'Beans')
, names(flow)
, flow)
df <- do.call(rbind, flow.df)
df
# State x Ingredient
# under.1 under 11 Beans
# under.2 under 13 Beans
使用@AndS建议的dplyr::data_frame
和dplyr::mutate
。让您避免使用if
语句:
library(dplyr)
flow <- list(over = setdiff(c(21, 23, 21), c(21, 23)),
under = setdiff(c(11, 13, 17), c(17)))
flow.df <- Map(function(State, x) data_frame(State, x)
, names(flow)
, flow)
df <- do.call(rbind, flow.df)
df %>% mutate(Ingredient = 'Beans')
# # A tibble: 2 x 3
# State x Ingredient
# * <chr> <dbl> <chr>
# 1 under 11.0 Beans
# 2 under 13.0 Beans
此后删除了评论的另一位评论者指出,您可以将rep
与times = length(x)
一起使用,其中x
是overflow
或underflow
flow <- list(over = setdiff(c(21, 23, 21), c(21, 23)),
under = setdiff(c(11, 13, 17), c(17)))
flow.df <- Map(function(State, x, len)
data.frame(State = rep(State, len)
, x
, Ingredient = rep('Beans', len))
, names(flow)
, flow
, lengths(flow))
df <- do.call(rbind, flow.df)
df
# State x Ingredient
# under.1 under 11 Beans
# under.2 under 13 Beans