如果元素存在于列表的所有子元素中,则删除该元素

时间:2016-06-19 00:49:41

标签: r

我遇到了在强制进入数据框之前要解析的列表。有时我的列表中包含我不期望的元素。我希望能够在出现时按名称删除所有这些意外元素。下面是一个带有元素wackything的列表示例,我希望将其删除,而无需调用元素索引或使用for循环遍历每个子元素。

my_list <- list(person = list(name = "mike", phone = "111-1111"), 
 person = list(name = "lisa", phone = "222-2222", wackything = "PLEASE REMOVE ME"),
 person = list(name = "kimo", phone = "333-3333"))

我希望我的最终名单看起来像这样:

final_list <- list(person = list(name = "mike", phone = "111-1111"), 
            person = list(name = "lisa", phone = "222-2222"),
            person = list(name = "kimo", phone = "333-3333"))

这样我就可以使用

将其核心化为数据框
do.call(rbind, lapply(final_list, rbind))

3 个答案:

答案 0 :(得分:6)

我认为你在预期的使用中有太多的啰嗦。看看这是否令人满意:

> rmwac <- function(x) x[ !names(x) %in% "wackything"]
> do.call(rbind, lapply(my_list, rmwac))
       name   phone     
person "mike" "111-1111"
person "lisa" "222-2222"
person "kimo" "333-3333"

请注意,epi10的完美答案使用了负号,这是可能的,因为grep返回数值,并且可以使用数值索引列表。但是,不能使用带有字符和逻辑值的负号。

答案 1 :(得分:5)

即使并非所有列表共享相同的元素名称,bind_rows包中的

dplyr也会起作用。然后,您可以删除不需要的列。

library(dplyr)

df = bind_rows(my_list)
   name    phone       wackything
1  mike 111-1111               NA
2  lisa 222-2222 PLEASE REMOVE ME
3  kimo 333-3333               NA
df = df[ , -grep("wackything", names(df))]
   name    phone
1  mike 111-1111
2  lisa 222-2222
3  kimo 333-3333

答案 2 :(得分:2)

你可以试试这个。第一步类似于42 - 的回答。然后我们使用sapply,它返回一个我们必须转置的矩阵。

my_list <- lapply(my_list, function(x)x[names(x)!= "wackything"])
data.frame(t(sapply(my_list,c)), row.names=NULL)

#  name    phone
#1 mike 111-1111
#2 lisa 222-2222
#3 kimo 333-3333

另一个可以提供相同结果的选项。

data.frame(Reduce(rbind, my_list), row.names=NULL)

我们在构建数据框时使用row.names=NULL。你可以不用这样做,但会产生与我们拥有的重复rownames相关的警告信息。