【问题标题】:R: How to get a value in data frame column depending on sequence and values in other columnsR:如何根据其他列中的序列和值获取数据框列中的值
【发布时间】:2015-12-07 06:51:26
【问题描述】:

我有一个数据框,df。我按 v1 和 v2 排序的数据帧。 对于 v1 中的每组唯一值(样本数据中的值 1、2 和 3),我想计算一个新变量 v5。

v5 的值取决于 v3 和 v4 的值: 如果 v3 == “新”,则 v5 == v4。 如果 v3 == "Old" 则 v5 在 v3 中第一个前面的值等于 "New" 的行中获取 v4 的值。都在 v1 的同一个“组”中。

样本数据:

df <- data.frame(v1=c(1,1,1,2,2,2,3,3,3,3), 
             v2=c(1,2,3,1,2,3,1,2,3,4),
             v3=c("New", "Old", "Old","New", "Old", "New","New", "New", "Old","Old"),
             v4=c("A","B","C","X","Y","Z","A","B","C","D")) 


v1 v2  v3 v4
1  1 New  A  
1  2 Old  B
1  3 Old  C
2  1 New  X
2  2 Old  Y
2  3 New  Z
3  1 New  A
3  2 New  B
3  3 Old  C
3  4 Old  D

期望的输出:

   v1 v2  v3 v4 v5
    1  1 New  A  A
    1  2 Old  B  A
    1  3 Old  C  A
    2  1 New  X  X
    2  2 Old  Y  X
    2  3 New  Z  Z
    3  1 New  A  A
    3  2 New  B  B
    3  3 Old  C  B
    3  4 Old  D  B

【问题讨论】:

    标签: r


    【解决方案1】:

    也可以使用dplyr 包。

    library(dplyr)
    library(zoo)
    df <- data.frame(v1=c(1,1,1,2,2,2,3,3,3,3), 
                     v2=c(1,2,3,1,2,3,1,2,3,4),
                     v3=c("New", "Old", "Old","New", "Old", "New","New", "New", "Old","Old"),
                     v4=c("A","B","C","X","Y","Z","A","B","C","D"),
                     stringsAsFactors = FALSE) 
    df %>% 
      group_by(v1) %>%
      mutate(v5=ifelse(v3=="New", v4, NA),
             v5=na.locf(v5))
    # Source: local data frame [10 x 5]
    # Groups: v1 [3]
    # 
    #       v1    v2    v3    v4    v5
    #    (dbl) (dbl) (chr) (chr) (chr)
    # 1      1     1   New     A     A
    # 2      1     2   Old     B     A
    # 3      1     3   Old     C     A
    # 4      2     1   New     X     X
    # 5      2     2   Old     Y     X
    # 6      2     3   New     Z     Z
    # 7      3     1   New     A     A
    # 8      3     2   New     B     B
    # 9      3     3   Old     C     B
    # 10     3     4   Old     D     B
    

    【讨论】:

    • 太棒了。谢谢@ docendo discimus
    【解决方案2】:

    我们可以试试data.table。将'data.frame'转换为'data.table'(setDT(df)),按'v1'分组,我们replace'v4'元素对应'v3'中的'Old'值,NA然后使用na.locf(来自library(zoo))要将NA 值替换为前面的非NA 值,分配(:=)输出以创建新列'v5'。

    library(data.table)
    library(zoo)
    setDT(df)[, v5:= na.locf(replace(v4, v3=='Old', NA)) , by = v1]
    df
    #    v1 v2  v3 v4 v5
    # 1:  1  1 New  A  A
    # 2:  1  2 Old  B  A
    # 3:  1  3 Old  C  A
    # 4:  2  1 New  X  X
    # 5:  2  2 Old  Y  X
    # 6:  2  3 New  Z  Z
    # 7:  3  1 New  A  A
    # 8:  3  2 New  B  B
    # 9:  3  3 Old  C  B
    #10:  3  4 Old  D  B
    

    或者我们可以使用来自base Rave

    df$v5 <- with(df, ave(replace(v4, v3=='Old', NA),v1, FUN= na.locf)) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      相关资源
      最近更新 更多