【问题标题】:R dplyr Replace unique values from one data frame with unique values from other data frame with unequal row numbersR dplyr 将来自一个数据帧的唯一值替换为来自具有不相等行号的另一数据帧的唯一值
【发布时间】:2020-08-21 15:15:36
【问题描述】:

我想用另一个 df 中的唯一 ID 替换一个 df 中的唯一 ID。 假设 df_long 包含每次试验的时间序列数据,而 df_short 仅包含一段时间内的平均值。

  1. 如果我必须在 group_by 中使用 ID 进行分组,我如何改变 ID 中的值?
  2. 如何应用从 unique(df_long$ID) 到 unique(df_short$ID) 的唯一值列表 如果数据框的行号不相等?

你会如何使用 dplyr 来做到这一点?

#let's assume this df contains averaged trials 
df_short <- data.frame(ID = rep(1:4,each=9), 
                 Trial= rep(1:3,12),  
                 Session = rep(rep(1:3,each=3),4) ) 

df_long <- data.frame(ID = rep(c(11,13,18,19),each=3*3*3), 
                 Trial= rep(rep(c(1,2,3),each=3),4*3),  
                 Time = rep(1:3,3*4*3),
                 Session = rep(rep(1:3,each=9),4))    

    df_short[1:15,]
       ID Trial Session
    1   1     1       1
    2   1     2       1
    3   1     3       1
    4   1     1       2
    5   1     2       2
    6   1     3       2
    7   1     1       3
    8   1     2       3
    9   1     3       3
    10  2     1       1
    11  2     2       1
    12  2     3       1
    13  2     1       2
    14  2     2       2
    15  2     3       2

df_long[1:15,]
   ID Trial Time Session
1  11     1    1       1
2  11     1    2       1
3  11     1    3       1
4  11     2    1       1
5  11     2    2       1
6  11     2    3       1
7  11     3    1       1
8  11     3    2       1
9  11     3    3       1
10 11     1    1       2
11 11     1    2       2
12 11     1    3       2
13 11     2    1       2
14 11     2    2       2
15 11     2    3       2

结果

 ID Trial Session
1  11     1       1
2  11     2       1
3  11     3       1
4  11     1       2
5  11     2       2
6  11     3       2
7  11     1       3
8  11     2       3
9  11     3       3
10 13     1       1
11 13     2       1
12 13     3       1
13 13     1       2
14 13     2       2
15 13     3       2

【问题讨论】:

  • 您如何知道要替换哪些 ID?也就是说,为什么df_short$ID1 变成11,而不是13?是根据它们第一次出现的顺序吗?
  • @GregorThomas 在这种情况下 ID 号是任意的,但每个数据帧中有 4 个。我想分别用 11,13,18,19 替换 1:4。如果您运行代码,则 df_long 在 ID col 中不仅仅是 11 的值。我只打印了前 15 行,因为它很长。
  • 对不起,没有意识到你分享了一个完整的例子,只打印了一部分。
  • 我的主要问题是关于逻辑。在您的评论中,您说“分别”,这使我认为确实是基于顺序-df_short 中的第一个ID 为1,df_long 中的第一个ID 为11,因此将1 替换为11,等等。这是正确的逻辑吗?

标签: r dplyr


【解决方案1】:

如果要“分别”(按发生顺序)进行替换,这里有两个选项。在这两种情况下,我都会创建一个新列,以便验证结果 - 我将删除旧列并重命名新列,由您决定。

# Option 1: with factor conversion
df_short %>%
  mutate(
    new_ID = factor(ID, levels = unique(ID), labels = unique(df_long$ID)),
    new_ID = as.numeric(as.character(new_ID)) # convert to numeric
)

# Option 2: make a look-up table and join
id_lookup = tibble(ID = unique(df_short$ID), new_ID = unique(df_long$ID))
df_short %>% left_join(id_lookup, by = "ID")

如果您的数据按 ID 列分组,在执行这些操作之前,您应该ungroup(),应用这些功能,并在必要时再次group_by()。 (该连接适用于分组数据,但如果数据已分组,您将无法删除旧的 ID 列。)

【讨论】:

  • 抱歉耽搁了这么久。你的代码就像一个魅力。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
相关资源
最近更新 更多