【问题标题】:R lapply return empty data frameR lapply返回空数据框
【发布时间】:2020-01-04 22:25:13
【问题描述】:

我正在尝试将列表中的数据移动到数据框中。当我运行数据路径时,如:

RequestData[["rows"]][["elements"]][[1]][["distance"]][["text"]]

我得到了结果:

[1] "8.4 km"

但是当我在函数中使用相同的路径时:

disData <- lapply(seq_along(RequestData), function(x){         
                  Dis_km <- RequestData[["rows"]][["elements"]][[x]][["distance"]][["text"]]
                  Duration <- RequestData[["rows"]][["elements"]][[x]][["duration"]][["text"]]
                  ID <- all_articles[x,"id"]

                  if (is.data.frame(Dis_km) && nrow(Dis_km)>0){

                    res_df <- data.frame(
                                         distanca=Dis_km,
                                         Duration=Duration,
                                         Id = ID
                                                )
                      }
              }) 

函数返回一个空对象disData。

备注:函数中的对象all_articles是另一个独立的数据框。

此数据在列表中: :

RequestData
$destination_addresses
[1] "Maršala Tita 62, Sarajevo 71000, Bosnia and Herzegovina"

$origin_addresses
 [1] "Mustafe Latifića, Sarajevo 71000, Bosnia and Herzegovina"         "Porodice Ribar, Sarajevo 71000, Bosnia and Herzegovina"          
 [3] "Skenderija & Adila Grebe, Sarajevo 71000, Bosnia and Herzegovina" "Azize Šaćirbegović, Sarajevo 71000, Bosnia and Herzegovina"      
 [5] "Bosanska, Sarajevo 71000, Bosnia and Herzegovina"                 "Jezero, Sarajevo 71000, Bosnia and Herzegovina"                  
 [7] "Behdžeta Mutevelića, Sarajevo 71000, Bosnia and Herzegovina"      "Emila Zole, Sarajevo 71000, Bosnia and Herzegovina"              
 [9] "Braće Begić, Sarajevo 71000, Bosnia and Herzegovina"              "Porodice Ribar, Sarajevo 71000, Bosnia and Herzegovina"          
[11] "Nedima Filipovića, Sarajevo 71000, Bosnia and Herzegovina"        "Telali, Sarajevo 71000, Bosnia and Herzegovina"                  
[13] "Ohridska, Sarajevo, Bosnia and Herzegovina"                       "Muse Ćazima Ćatića, Sarajevo 71000, Bosnia and Herzegovina"      
[15] "Džemala Bijedića, Sarajevo, Bosnia and Herzegovina"               "Ferde Hauptmana, Sarajevo 71000, Bosnia and Herzegovina"         
[17] "Bakarevićeva & Bistrik, Sarajevo 71000, Bosnia and Herzegovina"   "Vratnik Mejdan, Sarajevo 71000, Bosnia and Herzegovina"          
[19] "Mis Irbina, Sarajevo 71000, Bosnia and Herzegovina"               "Koševo, Sarajevo 71000, Bosnia and Herzegovina"                  

$rows
                                 elements
1  8.4 km, 8432, 1 hour 47 mins, 6413, OK
2         3.5 km, 3538, 46 mins, 2779, OK
3            0.7 km, 692, 9 mins, 552, OK
4         3.9 km, 3863, 50 mins, 3023, OK
5  6.3 km, 6275, 1 hour 19 mins, 4761, OK
6           0.8 km, 838, 11 mins, 655, OK
7         3.2 km, 3196, 41 mins, 2460, OK
8  7.9 km, 7898, 1 hour 43 mins, 6163, OK
9         2.4 km, 2413, 31 mins, 1842, OK
10        3.5 km, 3538, 46 mins, 2779, OK
11        4.0 km, 4041, 53 mins, 3165, OK
12          0.9 km, 937, 12 mins, 713, OK
13        2.8 km, 2837, 41 mins, 2432, OK
14           0.6 km, 611, 7 mins, 438, OK
15        4.5 km, 4507, 59 mins, 3550, OK
16        4.0 km, 4034, 53 mins, 3162, OK
17         1.0 km, 1039, 14 mins, 814, OK
18        1.6 km, 1564, 20 mins, 1215, OK
19           0.6 km, 595, 8 mins, 470, OK
20        1.9 km, 1883, 24 mins, 1425, OK

$status
[1] "OK"

第一个元素的列表结构如下所示:

有什么问题? 谢谢!

【问题讨论】:

  • 在数据框中,您是否希望destination_addresses 和status 重复所有行的值,还是只为第一行指定值,其余为null?
  • 不是。我只想从路径 $rows$elements$distance 和路径 $rows$elements$duration 中获取值,然后将它们与另一个数据框(all_articles)中的 id 合并
  • 您还可以分享列表元素的结构吗?显然元素行中有一个数据框,但不清楚它包含哪些列名。还有对 all_articles 的引用,但不清楚它指的是什么。
  • 我添加了必要的信息。
  • 请检查给出的答案

标签: r list dataframe lapply


【解决方案1】:

因此,有一种比使用 apply 系列更好的方法来解决您的问题,您还可以完全控制您的数据框并轻松操作它,大多数情况下您将使用 dplyr 和 purrr 包,如下所示;

元素创建

# Creating original list
destination_addresses = c("Maršala Tita 62, Sarajevo 71000, Bosnia and Herzegovina")

origin_addresses = c("Mustafe Latifića, Sarajevo 71000, Bosnia and Herzegovina",
                     "Porodice Ribar, Sarajevo 71000, Bosnia and Herzegovina",
                     "Skenderija & Adila Grebe, Sarajevo 71000, Bosnia and Herzegovina",
                     "Azize Šaćirbegović, Sarajevo 71000, Bosnia and Herzegovina",   
                     "Bosanska, Sarajevo 71000, Bosnia and Herzegovina",
                     "Jezero, Sarajevo 71000, Bosnia and Herzegovina",
                     "Behdžeta Mutevelića, Sarajevo 71000, Bosnia and Herzegovina",
                     "Emila Zole, Sarajevo 71000, Bosnia and Herzegovina",
                     "Braće Begić, Sarajevo 71000, Bosnia and Herzegovina",
                     "Porodice Ribar, Sarajevo 71000, Bosnia and Herzegovina",
                     "Nedima Filipovića, Sarajevo 71000, Bosnia and Herzegovina",
                     "Telali, Sarajevo 71000, Bosnia and Herzegovina",
                     "Ohridska, Sarajevo, Bosnia and Herzegovina",
                     "Muse Ćazima Ćatića, Sarajevo 71000, Bosnia and Herzegovina",
                     "Džemala Bijedića, Sarajevo, Bosnia and Herzegovina",
                     "Ferde Hauptmana, Sarajevo 71000, Bosnia and Herzegovina",
                     "Bakarevićeva & Bistrik, Sarajevo 71000, Bosnia and Herzegovina",
                     "Vratnik Mejdan, Sarajevo 71000, Bosnia and Herzegovina",
                     "Mis Irbina, Sarajevo 71000, Bosnia and Herzegovina",
                     "Koševo, Sarajevo 71000, Bosnia and Herzegovina")

status = c("OK")

# Please note this is a sample of rows only
rows <- list(elements = list(
  list(distance = data.frame(text = c("8.4 km"), value = 8432, stringsAsFactors = FALSE),
       duration = data.frame(text = c("1 hour 47 mins"), value = 6413, 
                             stringsAsFactors = FALSE)),
  list(distance = data.frame(text = c("3.5 km"), value = 8432, stringsAsFactors = FALSE),
       duration = data.frame(text = c("46 mins"), value = 6413, stringsAsFactors = FALSE))))

# Creating final list
RequestData <- list(
  destination_addresses = destination_addresses,
  origin_addresses = origin_addresses,
  rows = rows,
  status = status
)

# All articles dataframe
all_articles <-
  data.frame(
    id = c("ID1", "ID2", "ID3", "ID4", "ID5", "ID6")
  )

方法一:使用地图功能(推荐)

步骤:

我将在 RequestData$rows$elements 上循环,以便输出是一个数据框
2. 在每个元素中,我将循环其元素,即 RequestData$rows$elements[[1]]
3.然后我将这个元素转换成数据框
4. 现在两个循环完成后,map_df 会自动将所有内容绑定到数据帧中

library(purrr)
library(dplyr)

disData <-
  1:length(RequestData$rows$elements) %>% # We loop on elements
  map_df(function(x){
    tibble( # Access required elements from list
      distance = RequestData$rows$elements[[x]][["distance"]][["text"]],
      duration = RequestData$rows$elements[[x]][["duration"]][["text"]],
      Id = all_articles[x, "id"])
  })

disData
# # A tibble: 2 x 3
# distance duration       Id   
# <chr>    <chr>          <fct>
# 8.4 km   1 hour 47 mins ID1  
# 3.5 km   46 mins        ID2  

方法2:使用lapply

如果您希望在创建时使用 lapply 保留它,以下是代码的问题

  1. 应该是 seq_along(RequestData$rows$elements) 因为你想在元素上循环
  2. if (is.data.frame(Dis_km) && nrow(Dis_km)>0) 永远不会为真,因为 Dis_km 是单个字符而不是数据帧,这里的数据帧是 RequestData$rows$elements[[1]]
  3. lapply 的结果将是您需要绑定它们以将其转换为单个数据帧的数据帧列表

这里是修复后的代码;

disData <- lapply(seq_along(RequestData$rows$elements), function(x){  
  Dis_km <- RequestData[["rows"]][["elements"]][[x]][["distance"]][["text"]]
  Duration <- RequestData[["rows"]][["elements"]][[x]][["duration"]][["text"]]
  ID <- all_articles[x,"id"]

  if (length(Dis_km) > 0){
    res_df <- data.frame(
      distanca = Dis_km,
      Duration = Duration,
      Id = ID
    )
  }
})

disData <- do.call("rbind", disData)
disData
# distanca       Duration  Id
# 8.4 km 1 hour 47 mins ID1
# 3.5 km        46 mins ID2

【讨论】:

  • 谢谢纳拉门。我将举第一个例子。
猜你喜欢
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2018-05-21
  • 2017-09-02
  • 1970-01-01
  • 2019-02-04
  • 2018-04-26
  • 1970-01-01
相关资源
最近更新 更多