迭代获取数据框列的最大值,加一并重复 r 中的所有行

Posted

技术标签:

【中文标题】迭代获取数据框列的最大值,加一并重复 r 中的所有行【英文标题】:Iteratively get the max of a data frame column, add one and repeat for all rows in r 【发布时间】:2021-09-11 02:57:42 【问题描述】:

我需要执行一个数据库操作,将新数据添加到现有表中,然后为新行分配一个唯一 ID。我在 R 中询问这个问题,所以我可以在尝试用 sql 或 pyspark 重写之前直接了解逻辑。

假设我已经将新数据添加到现有数据中。以下是它的简化版本:

library(tidyverse)

df <- tibble(id = c(1, 2, 3, NA, NA),
             descriptions = c("dodgers", "yankees","giants", "orioles", "mets"))

# A tibble: 5 x 2
     id descriptions
  <dbl> <chr>       
1     1 dodgers     
2     2 yankees     
3     3 giants      
4    NA orioles     
5    NA mets 

我想要的是:

# A tibble: 5 x 2
     id descriptions
  <dbl> <chr>       
1     1 dodgers     
2     2 yankees     
3     3 giants      
4     4 orioles     
5     5 mets 

我不能使用 arrangerowid_to_columns id 被删除。

为了在不更改现有行的情况下为NA 行获取唯一 ID,我想获取 id 列的最大值,添加一个,将 NA 替换为该值,然后移至下一行。我的直觉是做这样的事情:df %&gt;% mutate(new_id = max(id, na.rm = TRUE) + 1) 但这只会得到最大值加一,而不是每行的新最大值。我觉得我可以使用映射函数来做到这一点,但我尝试过返回的结果与输入数据帧相同:

df %>% 
  mutate(id = ifelse(is.na(id),
                     map_dbl(id, ~max(.) + 1, na.rm = FALSE),
                     id))

# A tibble: 5 x 2
     id descriptions
  <dbl> <chr>       
1     1 dodgers     
2     2 yankees     
3     3 giants      
4    NA orioles     
5    NA mets  

在此先感谢——如果有人可以直接在 sql 中帮助我,那也是一个加号!

【问题讨论】:

好的,谢谢。已编辑。 我提供的解决方案有什么问题 【参考方案1】:

SQL 选项,使用sqldf 进行演示:

sqldf::sqldf("
  with cte as (
    select max(id) as maxid from df
  )
  select cte.maxid + row_number() over () as id, df.descriptions
  from df
    left join cte where df.id is null
  union
  select * from df where id is not null")
#   id descriptions
# 1  1      dodgers
# 2  2      yankees
# 3  3       giants
# 4  4      orioles
# 5  5         mets

【讨论】:

你不是说“直接用sql帮我”吗?我将 SQL 解释为首选解决方案 ... 我收到此错误:Error in SQL statement: AnalysisException: Window function row_number() requires window to be ordered, please add ORDER BY clause. For example SELECT row_number()(value_expr) OVER (PARTITION BY window_partition ORDER BY window_ordering) from table; 尝试将其更改为cte.maxid + row_number() over (order by id) as id。您使用的是什么 DBMS? 这是火花 对,对不起,你之前说过。我检查了一些随机来源,虽然我找不到order by 是否是必需的,但所有使用row_number() 的示例都包括order by,所以也许这就是关键。我希望这行得通……而且我不是火花专家。【参考方案2】:

这是一种方法,我们将 max 值与基于 NA 值的逻辑向量的累积和相加,并将 coalesce 与原始列“id”相加

library(dplyr)
df <- df %>% 
   mutate(id =  coalesce(id, max(id, na.rm = TRUE) + cumsum(is.na(id))))

-输出

df
# A tibble: 5 x 2
     id descriptions
  <dbl> <chr>       
1     1 dodgers     
2     2 yankees     
3     3 giants      
4     4 orioles     
5     5 mets       

【讨论】:

以上是关于迭代获取数据框列的最大值,加一并重复 r 中的所有行的主要内容,如果未能解决你的问题,请参考以下文章

如何在循环中读取数据框列值并检查每列的数据类型

如何访问 pandas 数据框列中的字典元素并对其进行迭代以创建填充有各自值的新列?

如何迭代数据列的每个单元格,转换和附加每个单元格?

根据另一列的值过滤数据框列[重复]

R:分配数据框列的变量标签

如何在此数据框列的 R 中正确使用 apply?