使用apply family创建新列

时间:2017-11-04 21:56:56

标签: r apply lapply

在我的数据框中,我有一个字符列。我想使用我自己编写的函数从现有的字符列创建一个新列。

我的功能

lat_finder <- function(coord){
return(as.numeric(substr(strsplit(coord,",")[[1]][1],2,10)))}

测试数据框

test <- data.frame('loc' = c("(37.7862913318072, -122.401375181471)","(37.7646938184545, -122.449439257453)","(37.7860078381928, -122.430650176965)"))

我正在尝试这个

test['Lat'] <- lapply(test['loc'],lat_finder)

结果是一个新列,但只有第一行函数的结果,即第一个lat应该是37.786 ......这是新列中每一行的值。我知道for循环会起作用,因为我之前已经完成了这个操作,但需要一段时间,所以我真的想加快速度。我确定很清楚我在这里缺少一些东西,所以除了修复之外,我还要感谢我的代码在做什么。

2 个答案:

答案 0 :(得分:1)

我不完全确定你想要的结果是什么,但这是否接近?

test <- data.frame(loc = c("(37.7862913318072, -122.401375181471)",
                           "(37.7646938184545, -122.449439257453)",
                           "(37.7860078381928, -122.430650176965)"))
test$loc <- gsub("[\\(\\)]", "", test$loc)
lonlat <- do.call(rbind, strsplit(test$loc,","))
lonlat <- matrix(as.numeric(lonlat), nrow(lonlat))
lonlat

#          [,1]      [,2]
# [1,] 37.78629 -122.4014
# [2,] 37.76469 -122.4494
# [3,] 37.78601 -122.4307

答案 1 :(得分:0)

初步说明 - 因为您对data.frame的调用缺少stringsAsFactors = FALSE您将输入字符串转换为一个因子,这使得问题在您说明时不可重复。那说我认为这可能只是你的测试代码中的一个问题,而不是你实际问题的根源,我正在添加它并从那里开始:

test_f <- data.frame('loc' = c("(37.7862913318072, -122.401375181471)",
                           "(37.7646938184545, -122.449439257453)",
                           "(37.7860078381928, -122.430650176965)"),
                 stringsAsFactors = FALSE)

话虽如此,您的根本问题是您拉动“loc”列的方式。这个方括号,字符串名称选择拉出一列数据帧:

> your_pull <- test_f['loc']
> your_pull
                                    loc
1 (37.7862913318072, -122.401375181471)
2 (37.7646938184545, -122.449439257453)
3 (37.7860078381928, -122.430650176965)
> typeof(your_pull)
[1] "list"
> class(your_pull)
[1] "data.frame"

lapply期待一个向量作为输入,您可以使用经典的$表示法获得:

> dollar_pull <- test_f$loc
> dollar_pull
[1] "(37.7862913318072, -122.401375181471)" "(37.7646938184545, -122.449439257453)"
[3] "(37.7860078381928, -122.430650176965)"
> typeof(dollar_pull)
[1] "character"
> class(dollar_pull)
[1] "character"

函数调用现在有效(希望你得到一个你可能想要一个向量的列表 - 请参阅下面的附带说明):

> lapply(test_f$loc,lat_finder)
[[1]]
[1] 37.78629

[[2]]
[1] 37.76469

[[3]]
[1] 37.78601

一些杂事:

1)也可以将新列分配为$

2)您可能希望使用sapply或vapply,这将生成一个向量而不是新data.frame列的列表。

3)你可能想放弃Hadley Wickham的purr包的申请系列。作为参考,这里的调用将是purrr::map_chr(test_f$loc, you_function)