迭代获取数据框列的最大值,加一并重复 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
我不能使用 arrange
和 rowid_to_columns
id 被删除。
为了在不更改现有行的情况下为NA
行获取唯一 ID,我想获取 id 列的最大值,添加一个,将 NA 替换为该值,然后移至下一行。我的直觉是做这样的事情:df %>% 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 中的所有行的主要内容,如果未能解决你的问题,请参考以下文章