【问题标题】:Populate 2 dataframe columns simultaneously?同时填充 2 个数据框列?
【发布时间】:2019-11-19 13:06:53
【问题描述】:

我有一个数据框,每行最多有 4 对不同的地理坐标。保存它们的字段是 LAT1 & LONG1、LAT2 & LONG2、LAT3 & LONG3 和 LAT4 & LONG4。这些在完整性上有所不同 - 通常有些值是 NA。我想创建列“LAT”和“LONG”,并用第一坐标填充这些列,其中两者都不是NA。我检查的顺序是 1、2、3、4。例如,我的数据可能如下所示:

ORD LAT1 LONG1     LAT2     LONG2     LAT3     LONG3     LAT4     LONG4
1   NA   NA       NA        NA        44.65783 -65.86633 44.68800 -65.80183
2   NA   NA       NA        NA        44.67033 -65.81833 44.67333 -65.84767
3   NA   NA       44.19133  -63.32017 44.25583 -63.27117 NA        NA
4   NA   NA       44.25717  NA        44.30950 -63.18617 NA        NA
5   NA   NA       44.30667  -63.17550 44.35483 -63.08717 NA        NA
6   NA   NA       44.35433  -63.07267 44.30633 -63.12117 NA        NA

我想以这个结束:

ORD LAT1 LONG1     LAT2     LONG2     LAT3     LONG3     LAT4     LONG4      LAT       LONG
1   NA   NA       NA        NA        44.65783 -65.86633 44.68800 -65.80183  44.65783  -65.86633
2   NA   NA       NA        NA        44.67033 -65.81833 44.67333 -65.84767  44.67033  -65.81833
3   NA   NA       44.19133  -63.32017 44.25583 -63.27117 NA        NA        44.19133  -63.32017
4   NA   NA       44.25717  NA        44.30950 -63.18617 NA        NA        44.30950  -63.18617
5   NA   NA       44.30667  -63.17550 44.35483 -63.08717 NA        NA        44.30667  -63.17550
6   NA   NA       44.35433  -63.07267 44.30633 -63.12117 NA        NA        44.35433  -63.07267

我实际上已经通过以下 2 个ifelse 块实现了这一点,它们正在做我想要的:

set_df$LAT <- ifelse(is.na(set_df$LAT1) | is.na(set_df$LONG1),
                      ifelse(is.na(set_df$LAT2) | is.na(set_df$LONG2),
                          ifelse(is.na(set_df$LAT3) | is.na(set_df$LONG3), set_df$LAT4,set_df$LAT3),
                      set_df$LAT2),
                  set_df$LAT1)
set_df$LONG <- ifelse(is.na(set_df$LAT1) | is.na(set_df$LONG1),
                         ifelse(is.na(set_df$LAT2) | is.na(set_df$LONG2),
                                ifelse(is.na(set_df$LAT3) | is.na(set_df$LONG3), set_df$LONG4,set_df$LONG3),
                         set_df$LONG2),
                   set_df$LONG1)

所以我在这里的原因是,这让我觉得这是一种获取结果的低效方式,因为我实际上是在识别我想要两次的坐标对——第一个块只捕获 LAT,第二个块抓住LONG。

有没有一种方法可以同时获取两个值并将它们弹出到新列中?我非常喜欢只使用基本 R 解决方案。

编辑: 这里它使用@user2974951 的方法,但带有命名字段和所需的输出:

    tmp=apply(set_df,1,function(x){
      if (!is.na(x["LAT1"]) & !is.na(x["LONG1"])) {return(c(x[test1="LAT1"],x["LONG1"]))}
      else if (!is.na(x["LAT2"]) & !is.na(x["LONG2"])) {return(c(x["LAT2"],x["LONG2"]))}
      else if (!is.na(x["LAT3"]) & !is.na(x["LONG3"])) {return(c(x["LAT3"],x["LONG3"]))}
      else {return(c(x["LAT4"],x["LONG4"]))}
    })
    set_df = cbind(set_df,t(tmp))
    colnames(set_df)[colnames(set_df)=="1"] <- "LAT"
    colnames(set_df)[colnames(set_df)=="2"] <- "LONG"

【问题讨论】:

  • 是否可以接受使用循环的解决方案?
  • 要分配多个列,请尝试stackoverflow.com/questions/19528836/…等技术
  • @user2974951 - 我对此持开放态度,但考虑到我正在努力提高代码效率,我不确定这会更好吗?
  • @anotherfred - 谢谢!在您链接到的那个页面上,我也喜欢 Oscar de León 的回应。

标签: r dataframe


【解决方案1】:

这是使用 apply 的替代解决方案

tmp=apply(dat,1,function(x){
  if (!is.na(x[2]) & !is.na(x[3])) {return(c(x[2],x[3]))}
  else if (!is.na(x[4]) & !is.na(x[5])) {return(c(x[4],x[5]))}
  else if (!is.na(x[6]) & !is.na(x[7])) {return(c(x[6],x[7]))}
  else {return(c(x[8],x[9]))}
})

cbind(dat,t(tmp))

  ORD LAT1 LONG1     LAT2     LONG2     LAT3     LONG3     LAT4     LONG4        1         2
1   1   NA    NA       NA        NA 44.65783 -65.86633 44.68800 -65.80183 44.65783 -65.86633
2   2   NA    NA       NA        NA 44.67033 -65.81833 44.67333 -65.84767 44.67033 -65.81833
3   3   NA    NA 44.19133 -63.32017 44.25583 -63.27117       NA        NA 44.19133 -63.32017
4   4   NA    NA 44.25717        NA 44.30950 -63.18617       NA        NA 44.30950 -63.18617
5   5   NA    NA 44.30667 -63.17550 44.35483 -63.08717       NA        NA 44.30667 -63.17550
6   6   NA    NA 44.35433 -63.07267 44.30633 -63.12117       NA        NA 44.35433 -63.07267

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 2021-03-17
    • 1970-01-01
    • 2018-12-08
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    相关资源
    最近更新 更多