【问题标题】:Create new column using apply family使用应用族创建新列
【发布时间】:2017-11-04 21:56:55
【问题描述】:

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

我的功能

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 循环会起作用,因为我以前做过这个操作,但它需要很长时间,所以我真的很想加快速度。我确信很明显我在这里遗漏了一些东西,所以除了修复之外,我希望能解释一下我的代码正在做什么。

【问题讨论】:

  • 注意:在原始帖子中,我错误地引用了我正在使用的整个数据框。应该是 lapply(test['loc']....) 并且已经更正了。

标签: r apply lapply


【解决方案1】:

初始说明 - 因为您对 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)

【讨论】:

  • 感谢您的功能帮助和详尽的解释。
【解决方案2】:

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

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

【讨论】:

  • 您可能应该在某处添加as.numeric,因为您在每个X2 的开头都隐藏了一个“空格”。 (还有他们的factors。)
  • 非常聪明的解决方案。我也在寻找 apply 系列的解释,所以我不得不给 alex.h 答案,但我一定会记住这个技巧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-06
  • 1970-01-01
  • 2020-07-24
  • 2014-03-03
  • 2012-07-07
  • 2015-09-27
  • 2013-08-17
相关资源
最近更新 更多