首先,请让我知道我正在做的是不是对dplyr的不当使用,因为我不确定我是否以最佳方式实现了这一点。我有以下数据帧:
mydf = data.frame(user = c(7,7,7,7,7,7,7,8,8,8,8,8,8),
col1 = c('0','0','1','1','0','3','NULL','3','3','0','1','0','0'),
col2 = runif(n=13),
col3 = letters[1:13],
stringsAsFactors = FALSE)
> mydf
user col1 col2 col3
1 7 0 0.7607907 a
2 7 0 0.1580448 b
3 7 1 0.8063540 c
4 7 1 0.7331512 d
5 7 0 0.2433631 e
6 7 3 0.2357065 f
7 7 NULL 0.4864172 g
8 8 3 0.6806089 h
9 8 3 0.2229874 i
10 8 0 0.6187911 j
11 8 1 0.7617177 k
12 8 0 0.5884821 l
13 8 0 0.4985750 m
我想做的过滤有点罗嗦,但我会尝试-我想通过删除col1 == '0 '的所有行来过滤数据帧,如果该行出现在该用户的第一行之后,其中col1 == '1 '。(粗体表示我把原问题搞砸了,把0和1调换了)。
例如,对于用户7,第3行的col1 == '1 ',所以我想过滤第3行之后col1 == '0 '的所有行(在本例中,只有第5行)。然后,对于用户8,第11行是该用户的第一行,其中col1 == '1 ',因此我希望筛选第12和13行,因为col1 == '0 '。
我的最终输出应该是这样的:
> mydf
user col1 col2 col3
1 7 0 0.7607907 a
2 7 0 0.1580448 b
3 7 1 0.8063540 c
4 7 1 0.7331512 d
6 7 3 0.2357065 f
7 7 NULL 0.4864172 g
8 8 3 0.6806089 h
9 8 3 0.2229874 i
10 8 0 0.6187911 j
11 8 1 0.7617177 k
我试过以下方法,但不起作用。我认为添加一个rownums列,然后按用户分组,然后过滤我所描述的内容。我的想法是,我的过滤呼叫有问题:
mydf %>%
mutate(rownums = 1:nrow(mydf)) %>%
group_by(user) %>%
filter(!(col1 == "0" & rownums > min(which(col1 == "1"))))
# A tibble: 9 x 5
# Groups: col0 [2]
user col1 col2 col3 rownums
<dbl> <chr> <dbl> <chr> <int>
1 7 0 0.2088034 a 1
2 7 0 0.2081894 b 2
3 7 1 0.1825428 c 3
4 7 1 0.2143353 d 4
5 7 3 0.1979774 f 6
6 7 NULL 0.2990799 g 7
7 8 3 0.7808038 h 8
8 8 3 0.1694272 i 9
9 8 1 0.1526450 k 11
该输出与正确输出之间的区别在于,该输出也错误地过滤了原始数据帧的第10行。
任何帮助,这是赞赏!
编辑-我特别好奇group_by()%
第二版-我想我明白了!
mydf %>%
group_by(col0) %>%
mutate(rownums = 1:length(col0)) %>%
filter(!(col1 == "0" & rownums > min(which(col1 == "1"))))
简单地翻转突变()和group_by()调用的顺序,并稍微调整一下突变()调用,看起来已经完成了它。不过,我愿意听到更好的方法。
这是通过< code>dplyr得到的一个想法
library(dplyr)
df %>%
group_by(user) %>%
mutate(id1 = row_number(), new_col = max(which(col1 == 1)+1)) %>%
filter(!(col1 == 0 & id1 >= new_col))
这就给出了,
# A tibble: 10 x 6
# Groups: user [2]
user col1 col2 col3 id1 new_col
<dbl> <chr> <dbl> <chr> <int> <dbl>
1 7 0 0.54742608 a 1 5
2 7 0 0.89271859 b 2 5
3 7 1 0.48999057 c 3 5
4 7 1 0.17163211 d 4 5
5 7 3 0.96146770 f 6 5
6 7 NULL 0.31368382 g 7 5
7 8 3 0.82051455 h 1 5
8 8 3 0.30705440 i 2 5
9 8 0 0.18545358 j 3 5
10 8 1 0.04834678 k 4 5
可以通过稍微更新你的尝试来解决:
library(dplyr)
mydf %>%
group_by(user) %>%
filter(col1 != 0 | row_number() < which.max(col1 == 1))
# user col1 col2 col3
# <dbl> <chr> <dbl> <chr>
# 1 7 0 0.756522673 a
# 2 7 0 0.168314555 b
# 3 7 1 0.977254798 c
# 4 7 1 0.722721694 d
# 5 7 3 0.407849378 f
# 6 7 NULL 0.245335151 g
# 7 8 3 0.003423735 h
# 8 8 3 0.191716738 i
# 9 8 0 0.626846893 j
#10 8 1 0.546459621 k
使用filter
我们选择col1
不等于0的所有行或当前行小于该组第一次出现的索引1的那些行。
有一个< code>cumany函数,对这些连续条件很有用,如下所示:
mydf %>%
group_by(user) %>%
mutate(seen_one = cumany(col1 == "1")) %>%
filter(!seen_one | col1 != "0")
即使用seen_one
标记“1”
之后的所有行,然后将行保留在不满足其中一个条件的位置。(过滤器
的语义需要反转条件以“删除”行,!(一个
我有以下问题: 当使用 dplyr 在 group_by() 之后改变数字列时,如果一行只包含一个值,即使用 mutate 命令时的 NaN,则此值将失败。 因此,如果分组列包含数字,它将正确地分类为dbl,但只要一个组只有一个NaN实例,它就会失败,因为dplyr将该组定义为lgl,而所有其他组都是dbl。 我的第一个(也是更一般的问题)是:当使用group_by()时,有没有一种方法告诉dpl
我有以下数据集“df1”: 我使用“group_by”和“总结”根据“类”列的最小值对codfam进行分组 它工作正常,并返回如下结果: 现在,我将获得与函数“summarize”保留在数据集中的每个codfam相关的列“sex”的值,如下所示: 我试着用 但不幸的是,它不起作用。 任何帮助或建议将不胜感激,提前感谢!
我想对MySQL表中的行求和,然后合并和更新。我正试图在一天内把所有的重复付款加起来。我将发布我现有的查询,但有一些限制。 示例: 预期结果: 我试过这个循环。 问题1.我一次只能更新一个专栏。 问题2。我以编程方式遍历行并更新值,因为如果没有重复的值,则行不会得到更新。我必须写另一个查询来更新。也可以删除现有查询。 问题3。它只适用于两次付款。 在laravel雄辩合并(和)多行和更新中是否有任
在一个有四列的大数据框(“myfile”)中,我必须添加第五列,其中的值有条件地基于前四列。 更喜欢使用和的答案,主要是因为它在大型数据集中的速度。 我的数据框如下所示: 第五列(V5)的值基于一些条件规则: 现在我想使用函数在所有行上使用这些规则(以避免慢循环)。类似这样的事情(是的,我知道这样不行!): 结果应该是: 如何在dplyr中执行此操作?
我有一个名称重复的数据集。如果名称重复,我想创建一个值为1(TRUE)或0(FALSE)的新列。 这是我使用的代码: 或者 然而,我得到了上面可以看到的错误。 另一个想法是使用group_by,然后计算计数。喜欢: 但是,它不能返回原始数据帧后group_by
我正在尝试使用创建一个新列,该列的值基于特定的列。 最后一个数据帧示例(我正在尝试创建): 这个问题基本上与此相反:dplyr-mutate:使用动态变量名。我不能使解决方案适应我的问题。