从列表corresp
和df_modifies
:
# Note : corresp must be a list and not a data.frame
corresp <- list(
a_remplacer = c("abricot1"),
remplacant = c("abricot2")
)
df_modifies <- data.frame(
produit = c("abricot1", "abricot2"),
m0123 = c(3, NA),
m0223 = c(2.5, NA),
m0323 = c(3, 2),
m0423 = c(NA, 3)
)
我希望得到以下结果:
produit m0123 m0223 m0323 m0423
1 abricot2 3 2.5 2 3
我的代码很长,我想用across
或{purrr}
来缩短它。
library(dplyr)
modifies <- data.frame(
produit = corresp$remplacant) |>
mutate(
m0123 = ifelse(is.na(df_modifies$m0123[df_modifies$produit %in% corresp$remplacant]),
df_modifies$m0123[which(!is.na(df_modifies$m0123))[1]],
df_modifies$m0123[df_modifies$produit %in% corresp$remplacant]),
m0223 = ifelse(is.na(df_modifies$m0223[df_modifies$produit %in% corresp$remplacant]),
df_modifies$m0223[which(!is.na(df_modifies$m0223))[1]],
df_modifies$m0223[df_modifies$produit %in% corresp$remplacant]),
m0323 = ifelse(is.na(df_modifies$m0323[df_modifies$produit %in% corresp$remplacant]),
df_modifies$m0323[which(!is.na(df_modifies$m0323))[1]],
df_modifies$m0323[df_modifies$produit %in% corresp$remplacant]),
m0423 = ifelse(is.na(df_modifies$m0423[df_modifies$produit %in% corresp$remplacant]),
df_modifies$m0423[which(!is.na(df_modifies$m0423))[1]],
df_modifies$m0423[df_modifies$produit %in% corresp$remplacant])
)
你能帮帮我吗?
3条答案
按热度按时间qmelpv7a1#
填写NA,然后填写子集:
jljoyd4f2#
我不确定这个答案的缩放版本如何工作,但你可以这样使用
across
:pdsfdshx3#
前两种方法使用tidyverse,第三种使用data.table。
1)proc_transpose/coalesce我们使用
proc_transpose
转置df_modifies
的m...
列,并使用coalesce
执行NA消除。最后再次使用proc_transpose
转换回原始形式。请注意,
proc_transpose
概念上id=
列移动到行名称NAME
列代码
**1a)pivot_**一种变体是使用
pivot_longer
,然后使用pivot_wider
来实现转置,最后使用pivot_wider
转置回来,如图所示:2)data.frame/fill另一种方法是将
corresp
转换为 Dataframe ,然后将其连接到df_modifies
,以便在name
上排序时将行按fill
应用于m...
列时的顺序排列。然后取最后一行并删除name
列。请注意,在示例中,
df_modifies
的行已经处于正确的顺序,因此如果我们知道我们可以避免使用corresp
和相关的排序,则解决方案仅为df_modifies %>% fill(starts_with("m")) %>% slice_tail(n = 1)
3)转置/fcoalesce这与(1)类似,只是它使用了带有
transpose
而不是pivot_*
的data.table更新
已经更新了很多次,以简化和添加替代品。