我想过滤掉var3 <5的所有值,同时保持var1的每个值至少出现一次.
> foo <- data.frame(var1=c(1, 1, 8, 8, 5, 5, 5), var2=c(1,2,3,2,4,6,8), var3=c(7,1,1,1,1,1,6))
> foo
var1 var2 var3
1 1 1 7
2 1 2 1
3 8 3 1
4 8 2 1
5 5 4 1
6 5 6 1
7 5 8 6
Run Code Online (Sandbox Code Playgroud)
subset(foo, (foo$var3>=5)) 会删除第2行到第6行,我会丢失var1 == 8.
这是我期望的结果:
var1 var2 var3
1 1 1 7
3 8 NA NA
7 5 8 6
Run Code Online (Sandbox Code Playgroud)
这是我得到的最接近的:
> foo$var3[ foo$var3 < 5 ] = NA
> foo$var2[ is.na(foo$var3) ] = NA
> foo
var1 var2 var3
1 1 1 7
2 1 NA NA
3 8 NA NA
4 8 NA NA
5 5 NA NA
6 5 NA NA
7 5 8 6
Run Code Online (Sandbox Code Playgroud)
现在我只需要知道如何有条件地删除右行(2,3 或 4,5,6):如果var2和var3是NA并且var1的值多于1次,则删除行.
但肯定有一种更简单/更优雅的方式来解决这个小问题.
编辑:更改foo为更像我的用例
Jor*_*eys 10
最快的方法是使用merge:
> merge(foo[foo$var3>5,],unique(foo$var1),by.x=1,by.y=1,all.y=T)
var1 var2 var3
1 1 1 7
2 5 8 6
3 8 NA NA
Run Code Online (Sandbox Code Playgroud)
unique(foo$var1)给出var1中的唯一值.这些映射针对var3大于5的数据帧.你得到每个参数的第一列(all.x = 1,all.y = 1),你说y中的所有值都应该被表示(all.y = T).另见?merge.
如果您想保留订单,那么:
> merge(foo[foo$var3>5,],unique(foo$var1),by.x=1,by.y=1,
+ all.y=T)[order(unique(foo$var1)),]
var1 var2 var3
1 1 1 7
3 8 NA NA
2 5 8 6
Run Code Online (Sandbox Code Playgroud)
merge对发生映射的变量进行排序.order给出了这种排序,因此你可以使用该顺序作为索引来反转它.另见?order.