R 如何根据列表中元素的长度对列表进行子集划分

R 如何根据列表中元素的长度对列表进行子集划分,r,list,subset,R,List,Subset,在R中,我有一个函数(来自包sp)可以为您提供的每个IP地址查找11个数据字段 我有一个名为IP.地址的IP列表: > head(ip.addresses) [1] "128.177.90.11" "71.179.12.143" "66.31.55.111" "98.204.243.187" "67.231.207.9" "67.61.248.12" 注意:这些或任何其他IP可用于重现此问题 因此,我使用sapply将函数应用于该对象: ips.info <

R
中,我有一个函数(
来自包
sp
)可以为您提供的每个IP地址查找11个数据字段

我有一个名为
IP.地址的IP列表

> head(ip.addresses)
[1] "128.177.90.11"  "71.179.12.143"  "66.31.55.111"   "98.204.243.187" "67.231.207.9"   "67.61.248.12"  
注意:这些或任何其他IP可用于重现此问题

因此,我使用
sapply
将函数应用于该对象:

ips.info     <- sapply(ip.addresses, ip2coordinates)
参数表示不同的行数:1,0

我的问题是--“如何删除缺少/不完整数据的元素,或者如何将此列表转换为每个IP地址有11列和1行的数据帧?”

我试过几种方法

  • 首先,我尝试编写一个循环来删除长度小于11的元素

    for (i in 1:length(ips.info)){
    if (length(ips.info[i]) < 11){
    ips.info[i] <- NULL}}
    
  • 我还尝试了
    complete.cases()
    ,看看它是否可能有用

    Error in complete.cases(ips.info) : not all arguments have the same length
    
  • 最后,我尝试了我的
    for
    循环的一个变体,该循环以
    长度(ips.info[[I]]==11
    为条件,并将完整的记录写入另一个对象,但不知怎的,它产生了ips.info的精确副本


这里有一种方法,您可以使用内置的
过滤器来实现这一点

#input data
library(RDSTK)
ip.addresses<-c("128.177.90.10","71.179.13.143","66.31.55.111","98.204.243.188",
    "67.231.207.8","67.61.248.15")
ips.info  <- sapply(ip.addresses, ip2coordinates)

#data.frame creation
lengthIs <- function(n) function(x) length(x)==n
do.call(rbind, Filter(lengthIs(11), ips.info))

基于
base
包的替代解决方案

  # find non-complete elements
  ids.to.remove <- sapply(ips.info, function(i) length(i) < 11)
  # remove found elements
  ips.info <- ips.info[!ids.to.remove]
  # create data.frame
  df <- do.call(rbind, ips.info)
#查找不完整的元素

ids.to.remove+1用于使用内置。我已经在运行RDSTK,所以我还没有回去验证您的解决方案,但它看起来不错。我认为
Filter
是一种更优雅的解决任务的方法。RDSTK提供的唯一功能是
ip2coordinates
函数。我使用的所有其他功能都是base R。
#input data
library(RDSTK)
ip.addresses<-c("128.177.90.10","71.179.13.143","66.31.55.111","98.204.243.188",
    "67.231.207.8","67.61.248.15")
ips.info  <- sapply(ip.addresses, ip2coordinates)

#data.frame creation
lengthIs <- function(n) function(x) length(x)==n
do.call(rbind, Filter(lengthIs(11), ips.info))
do.call(rbind, Filter(function(x) length(x)==11, ips.info))
  # find non-complete elements
  ids.to.remove <- sapply(ips.info, function(i) length(i) < 11)
  # remove found elements
  ips.info <- ips.info[!ids.to.remove]
  # create data.frame
  df <- do.call(rbind, ips.info)