【问题标题】:Ordering data based on two variables but with a cut-off point基于两个变量但有一个截止点的排序数据
【发布时间】:2020-06-23 06:06:52
【问题描述】:

我能够根据下面的数据构建一个新的数据框,其中每一行包含 ID 列中每个分类变量的期望值,按时间升序排列。但是我怎么能做到这一点,直到一个截止点。例如,如果我只想按时间顺序取值,直到时间 = 5。

library('dplyr')
library('purrr')
df <- read.csv("data.csv", header = TRUE)
# df
      ID Time Expectation
1  NJL.1    3         0.1
2  NJL.1    1         0.1
3  NJL.1    2         0.1
4  NJL.1    4         0.1
5  NJL.1    6         0.1
6  NJL.1    5       100.0
7  NJL.1   10         0.1
8  NJL.1    8         0.1
9  NJL.1    9         0.1
10 NJL.1    7         0.1
11 NJL.2   10         0.1
12 NJL.2    1         0.1
13 NJL.2    3         0.1
14 NJL.2    6         0.1
15 NJL.2    4         0.1
16 NJL.2    2         6.0
17 NJL.2    5         0.1
18 NJL.2    8         7.0
19 NJL.2    9         8.0
20 NJL.2    7         0.1
21 NJL.3    3         0.1
22 NJL.3    1         0.1
23 NJL.3    2         0.1
24 NJL.3    4         0.1
25 NJL.3    6         0.1
26 NJL.3    5        10.0
27 NJL.3   10         0.1
28 NJL.3    8         0.1
29 NJL.3    9         0.1
30 NJL.3    7         0.1

df <- df %>%
  group_by(ID) %>%
  summarise(var = list(Expectation[order(Time)]), 
            var_ts = purrr::map(var, ts))

例如,对于 NJL.1,值将是 (0.1, 0.1, 0.1, 0.1. 100) 并且所有其他期望值都将被忽略。

非常感谢!

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 没什么!我是新手:-)

标签: r dataframe data-manipulation


【解决方案1】:

这会将您的 df 子集化为所需的值:

df[which(df$Time <= 5),]    

        row    ID Time Expectation
 1:   1 NJL.1    3         0.1
 2:   2 NJL.1    1         0.1
 3:   3 NJL.1    2         0.1
 4:   4 NJL.1    4         0.1
 5:   6 NJL.1    5       100.0
 6:  12 NJL.2    1         0.1
 7:  13 NJL.2    3         0.1
 8:  15 NJL.2    4         0.1
 9:  16 NJL.2    2         6.0
10:  17 NJL.2    5         0.1
11:  21 NJL.3    3         0.1
12:  22 NJL.3    1         0.1
13:  23 NJL.3    2         0.1
14:  24 NJL.3    4         0.1
15:  26 NJL.3    5        10.0

要订购数据框,首先将其保存为dfnew

dfnew <- df[df$Time <= 3 & df$Time <= 5,]

然后简单地使用order 这样:

dfnew[order(ID, Time), ]

   row    ID Time Expectation
1:   2 NJL.1    1         0.1
2:   3 NJL.1    2         0.1
3:   1 NJL.1    3         0.1
4:  12 NJL.2    1         0.1
5:  16 NJL.2    2         6.0
6:  13 NJL.2    3         0.1
7:  22 NJL.3    1         0.1
8:  23 NJL.3    2         0.1
9:  21 NJL.3    3         0.1

【讨论】:

  • 哦,谢谢!如果我想在 time = 3 和 time = 5 之间进行子集化,代码将如何变化?
  • 那就是df[which(df$Time &lt;= 3 &amp; df$Time &lt;= 5),]。没有which 也能正常工作:df[df$Time &lt;= 3 &amp; df$Time &lt;= 5,]
【解决方案2】:

假设您确实想要按要求订购 Times,那么在基础 R 中您可以这样做

dat <- with(dat, {dat <- dat[Time <= 5, ];dat[order(ID, Time), ]})
dat
#       ID Time Expectation
# 2  NJL.1    1         0.1
# 3  NJL.1    2         0.1
# 1  NJL.1    3         0.1
# 4  NJL.1    4         0.1
# 6  NJL.1    5       100.0
# 12 NJL.2    1         0.1
# 16 NJL.2    2         6.0
# 13 NJL.2    3         0.1
# 15 NJL.2    4         0.1
# 17 NJL.2    5         0.1
# 22 NJL.3    1         0.1
# 23 NJL.3    2         0.1
# 21 NJL.3    3         0.1
# 24 NJL.3    4         0.1
# 26 NJL.3    5        10.0

数据

dat <- structure(list(ID = c("NJL.1", "NJL.1", "NJL.1", "NJL.1", "NJL.1", 
"NJL.1", "NJL.1", "NJL.1", "NJL.1", "NJL.1", "NJL.2", "NJL.2", 
"NJL.2", "NJL.2", "NJL.2", "NJL.2", "NJL.2", "NJL.2", "NJL.2", 
"NJL.2", "NJL.3", "NJL.3", "NJL.3", "NJL.3", "NJL.3", "NJL.3", 
"NJL.3", "NJL.3", "NJL.3", "NJL.3"), Time = c(3L, 1L, 2L, 4L, 
6L, 5L, 10L, 8L, 9L, 7L, 10L, 1L, 3L, 6L, 4L, 2L, 5L, 8L, 9L, 
7L, 3L, 1L, 2L, 4L, 6L, 5L, 10L, 8L, 9L, 7L), Expectation = c(0.1, 
0.1, 0.1, 0.1, 0.1, 100, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 
0.1, 6, 0.1, 7, 8, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 10, 0.1, 0.1, 
0.1, 0.1)), row.names = c(NA, -30L), class = "data.frame")

【讨论】:

    【解决方案3】:

    data.table 方法

    样本数据

    library(data.table)
    
    setDT(df)
    #or
    df <- fread("row ID Time Expectation
    1  NJL.1    3         0.1
    2  NJL.1    1         0.1
    3  NJL.1    2         0.1
    4  NJL.1    4         0.1
    5  NJL.1    6         0.1
    6  NJL.1    5       100.0
    7  NJL.1   10         0.1
    8  NJL.1    8         0.1
    9  NJL.1    9         0.1
    10 NJL.1    7         0.1
    11 NJL.2   10         0.1
    12 NJL.2    1         0.1
    13 NJL.2    3         0.1
    14 NJL.2    6         0.1
    15 NJL.2    4         0.1
    16 NJL.2    2         6.0
    17 NJL.2    5         0.1
    18 NJL.2    8         7.0
    19 NJL.2    9         8.0
    20 NJL.2    7         0.1
    21 NJL.3    3         0.1
    22 NJL.3    1         0.1
    23 NJL.3    2         0.1
    24 NJL.3    4         0.1
    25 NJL.3    6         0.1
    26 NJL.3    5        10.0
    27 NJL.3   10         0.1
    28 NJL.3    8         0.1
    29 NJL.3    9         0.1
    30 NJL.3    7         0.1")
    

    代码

    #set keys for sorting
    setkey( df, ID, Time )
    
    #filter values by group
    ans <- df[ df[, .I[Time <= 5], by = ID]$V1 ]
    #    row    ID Time Expectation
    # 1:   2 NJL.1    1         0.1
    # 2:   3 NJL.1    2         0.1
    # 3:   1 NJL.1    3         0.1
    # 4:   4 NJL.1    4         0.1
    # 5:   6 NJL.1    5       100.0
    # 6:  12 NJL.2    1         0.1
    # 7:  16 NJL.2    2         6.0
    # 8:  13 NJL.2    3         0.1
    # 9:  15 NJL.2    4         0.1
    # 10: 17 NJL.2    5         0.1
    # 11: 22 NJL.3    1         0.1
    # 12: 23 NJL.3    2         0.1
    # 13: 21 NJL.3    3         0.1
    # 14: 24 NJL.3    4         0.1
    # 15: 26 NJL.3    5        10.0
    

    现在您可以轻松地进行汇总、粘贴+折叠、dcast 等...以获得所需的输出。

    例子:

    ans[, .(values = paste0( Expectation, collapse = "," ) ), by = ID ]
    #       ID              values
    # 1: NJL.1 0.1,0.1,0.1,0.1,100
    # 2: NJL.2   0.1,6,0.1,0.1,0.1
    # 3: NJL.3  0.1,0.1,0.1,0.1,10
    

    dcast(ans, ID ~ Time, value.var = "Expectation")
    #       ID   1   2   3   4     5
    # 1: NJL.1 0.1 0.1 0.1 0.1 100.0
    # 2: NJL.2 0.1 6.0 0.1 0.1   0.1
    # 3: NJL.3 0.1 0.1 0.1 0.1  10.0
    

    【讨论】:

    • 感谢@Wimpel!如果我只想要 time = 2 和 time = 5 之间的期望值怎么办?
    • 没关系,我现在有答案了 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多