代码之家  ›  专栏  ›  技术社区  ›  Mus mzuba

为什么我的列表提取到一个数据帧,结果得到的值比列表包含的值少?

  •  -1
  • Mus mzuba  · 技术社区  · 7 年前

    我有大约200000个元素的列表。

    每个元素存储两个值并表示地图坐标(纬度和经度)。

    我想把这些值提取到 lat lon 到目前为止,各种变量都得出了这样的结论:

    for(i in nrow(users)) {
      lat[i] <- users$location[[i]][1]
      lon[i] <- users$location[[i]][2]
    }
    
    coords <- as.data.frame(cbind(lat, lon))
    

    据我所见,它似乎提取了第一个元素,然后在末尾提取了19个元素,两者之间没有任何差别(检查时总共20个元素 complete.cases )。

    理想情况下,我想排除 NA 0, 0 值也一样。

    直接查看列表,我可以看到这是错误的,因为其中包含多个值。

    如果我将最终的数据框架与列表项进行比较,这些数字就不匹配了。例如,值 -73.9924 存在于列表中,但不在我的数据框中。

    我哪里出错了?

    我的最终数据框架:

    > coords[complete.cases(coords), ]
                lat       lon
    1       37.4590 -122.1781
    96960   40.8152  -73.3624
    96961   40.0409  -75.6374
    96962   42.5153  -70.9075
    96963   33.7773  -84.3366
    96964   39.9831  -86.2876
    96965   40.7588  -73.9680
    96966   36.7646  -76.1990
    96967   44.7415  -91.3012
    96968   42.6179  -70.7154
    96969   40.5953  -74.6173
    96970   50.8000   -0.3667
    96971   34.0523 -118.3852
    96972   41.4468  -74.0689
    96973   26.9467  -80.2170
    96974   40.7139  -74.0079
    96975   34.2313 -118.1486
    96976   43.6655  -79.4378
    96977   39.0972  -84.1225
    96978 -122.1781   37.4590
    

    列表内容示例:

    [[734]]
    [1] 0 0
    
    [[735]]
    [1] 0 0
    
    [[736]]
    [1] 0 0
    
    [[737]]
    [1] 0 0
    
    [[738]]
    [1] -73.9924  40.7553
    
    [[739]]
    [1] 0 0
    
    [[740]]
    [1] -76.7818  39.4370
    
    [[741]]
    [1] -97.822  37.751
    
    [[742]]
    NULL
    
    [[743]]
    [1] 0 0
    
    [[744]]
    [1] 0 0
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   iod    7 年前

    不需要 for 循环。使用 sapply 具有 [ 作为功能:

    lat<-sapply(users$location,"[",1)
    lon<-sapply(users$location,"[",2)
    

    不知道跳过行的原因是什么,但是如果这仍然不起作用,我们可以从那里开始研究根本原因。

    如果你想避免 NULL s将此与您创建的两个向量一起使用:

    lat<-unlist(lat[!sapply(lat,is.null)])
    

    对伦来说也是如此。 或者,您可以在创建lat和lon之前对用户$location应用相同的逻辑-使用长列表可能更快。

    如果您希望所有内容都在一个(稍微)优雅的命令中,我建议您使用 多姿多彩 ,然后将其更改为data.frame:

    coords<-as.data.frame(t(sapply(users$location[!sapply(users$location,is.null)],"[",c(1,2)))) %>% 
    dplyr::rename(lat=V1,lon=V2) %>% 
    dplyr::filter(!lat==0,!lon==0)
    
        2
  •  0
  •   RLave    7 年前

    假设您有一个类似于我的示例中的列表,您可以使用 dplyr ,如下所示:

    require(dplyr)
    lista <- list(as.data.frame(matrix(c(0,0), nrow = 1)), 
              as.data.frame(matrix(c(37.4590,-122.1781), nrow = 1)), 
              as.data.frame(matrix(c(NA,NA), nrow = 1)), 
              as.data.frame(matrix(c(42.5153,-70.9075), nrow = 1))) # toy example
    names(lista) <- 1:4 # each element in the list has a name
    
    lista %>% 
      bind_rows() %>% 
      filter(!is.na(V1), !is.na(V2)) %>%  # here you remove NAs
      filter(V1 != 0, V2 != 0) # here you remove zeros