Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 在数据帧中,为列的每个元素查找下一个较小值的索引_R_Dplyr - Fatal编程技术网

R 在数据帧中,为列的每个元素查找下一个较小值的索引

R 在数据帧中,为列的每个元素查找下一个较小值的索引,r,dplyr,R,Dplyr,问题: 在dataframe中,我想创建一个新列作为现有列的下一个较小值的索引 例如,数据如下所示。它已经安排在项目,日期中 item day val 1 1 2 3 2 1 4 2 3 1 5 1 4 2 1 1 5 2 3 2 6 2 5 3 首先,我想使用dplyr中的groupby(item)来选择每个项目的子数据帧 然后,对于第1行,我向下查看行,发现第2行的val较小。这就是我想要

问题:

在dataframe中,我想创建一个新列作为现有列的下一个较小值的索引

例如,数据如下所示。它已经安排在
项目,日期中

  item day val 
1    1   2   3 
2    1   4   2 
3    1   5   1 
4    2   1   1 
5    2   3   2 
6    2   5   3 
首先,我想使用
dplyr
中的
groupby(item)
来选择每个项目的子数据帧

然后,对于第1行,我向下查看行,发现第2行的
val
较小。这就是我想要的,所以我记录了与该行对应的
天。第2行类似

请注意,对于第3行和第6行,它们是对应子数据帧的最后一行,因此没有下一个较小的值。对于第4行和第5行,当我向下查看行时,没有更小的
val

带有新列的dataframe应该如下所示

  item day val next.smaller.day
1    1   2   3                4
2    1   4   2                5
3    1   5   1               -1
4    2   1   1               -1
5    2   3   2               -1
6    2   5   3               -1
我想知道是否有任何方法可以使用
dplyr
来实现这一点,或者
r
中除了for循环之外的任何代码

我发现一条线索在问这个问题的算法。 这是相关的,并且提出的算法在时间复杂度方面优于我的算法,但我仍然发现在我的场景中很难实现

谢谢大家!

更新:

这里有另一个例子来重新说明我在寻找什么

  item day val next.smaller.day
1    1   2   2                5
2    1   4   3                5
3    1   5   1               -1
4    2   1   3                3
5    2   3   1               -1
6    2   5   2               -1

您可以按项目对数据进行分组,使用
diff
函数计算行与行之间的差异,并检查其是否小于零,这将生成一个逻辑向量,您可以使用该逻辑向量在第二天提取数据。由于您将在第二天取货,因此需要使用
lead
功能向前移动day列,以便它能够匹配您要放置它们的行

旁注:由于
diff
函数创建了一个比原始元素短一个的向量元素,并且每个组始终保留最后一行,因此我们可以使用
FALSE
条件填充
diff
结果

library(dplyr);
df %>% group_by(item) %>% mutate(smaller = c(diff(val) < 0, F), 
                                 next.smaller.day = ifelse(smaller, lead(day), -1)) %>%
       select(-smaller)

# Source: local data frame [6 x 4]
# Groups: item [2]

#    item   day   val next.smaller.day
#   <int> <int> <int>            <dbl>
# 1     1     2     3                4
# 2     1     4     2                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1
库(dplyr);
df%>%组(项目)%>%突变(较小=c(差异(val)<0,F),
next.smaller.day=ifelse(较小,领先(天),-1))%>%
选择(-较小)
#来源:本地数据帧[6 x 4]
#分组:项目[2]
#项目日期val下一个较小的日期
#                 
# 1     1     2     3                4
# 2     1     4     2                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1
更新:

find.next.small vec[-1]),
find.next.minger(ini+1,vec[-1]))
}#递归函数将逐元素遍历向量并找出
#下一个较小值的索引。
df%>%分组依据(项目)%>%变异(next.small.day=天[find.next.small(1,val)],
next.small.day=替换(next.small.day,is.na(next.small.day),-1))
#来源:本地数据帧[6 x 4]
#分组:项目[2]
#
#项目日期val下一个较小的日期
#                 
# 1     1     2     2                5
# 2     1     4     3                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1

您可以按项目对数据进行分组,使用
diff
函数计算行间差异,并检查其是否小于零,这将生成一个逻辑向量,您可以使用该逻辑向量在第二天提取。由于您将在第二天取货,因此需要使用
lead
功能向前移动day列,以便它能够匹配您要放置它们的行

旁注:由于
diff
函数创建了一个比原始元素短一个的向量元素,并且每个组始终保留最后一行,因此我们可以使用
FALSE
条件填充
diff
结果

library(dplyr);
df %>% group_by(item) %>% mutate(smaller = c(diff(val) < 0, F), 
                                 next.smaller.day = ifelse(smaller, lead(day), -1)) %>%
       select(-smaller)

# Source: local data frame [6 x 4]
# Groups: item [2]

#    item   day   val next.smaller.day
#   <int> <int> <int>            <dbl>
# 1     1     2     3                4
# 2     1     4     2                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1
库(dplyr);
df%>%组(项目)%>%突变(较小=c(差异(val)<0,F),
next.smaller.day=ifelse(较小,领先(天),-1))%>%
选择(-较小)
#来源:本地数据帧[6 x 4]
#分组:项目[2]
#项目日期val下一个较小的日期
#                 
# 1     1     2     3                4
# 2     1     4     2                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1
更新:

find.next.small vec[-1]),
find.next.minger(ini+1,vec[-1]))
}#递归函数将逐元素遍历向量并找出
#下一个较小值的索引。
df%>%分组依据(项目)%>%变异(next.small.day=天[find.next.small(1,val)],
next.small.day=替换(next.small.day,is.na(next.small.day),-1))
#来源:本地数据帧[6 x 4]
#分组:项目[2]
#
#项目日期val下一个较小的日期
#                 
# 1     1     2     2                5
# 2     1     4     3                5
# 3     1     5     1               -1
# 4     2     1     1               -1
# 5     2     3     2               -1
# 6     2     5     3               -1

谢谢您的回复。您所做的在给定的示例中起作用。但是,下一个较小的值可能不在下一行中。例如,如果
val
2,3,1
并且
day
2,4,5
,我希望输出是
5,5,-1
。您知道如何实现此功能吗?请参阅更新。您可以编写一个递归函数来查找下一个较小值的索引,然后使用
dplyr
函数应用它。非常感谢!我试图写一个函数来实现我的目标,但我想不出来。