我的问题无法解决:
数据:
df <- data.frame(f1=c("a", "a", "b", "b", "c", "c", "c"),
v1=c(10, 11, 4, 5, 0, 1, 2))
data.frame:f1 is factor
f1 v1
a 10
a 11
b 4
b 5
c 0
c 1
c 2
# What I want is:(for example, fetch data with the number of element of some level == 2, then to data.frame)
a b
10 4
11 5
谢谢!
答案 0 :(得分:2)
在这里我可能会遗漏一些简单的东西,但是下面使用dplyr
的方法是可行的。
library(dplyr)
nlevels = 2
df1 <- df %>%
add_count(f1) %>%
filter(n == nlevels) %>%
select(-n) %>%
mutate(rn = row_number()) %>%
spread(f1, v1) %>%
select(-rn)
这给
# a b
# <int> <int>
#1 10 NA
#2 11 NA
#3 NA 4
#4 NA 5
现在,如果您要删除NA
,我们可以
do.call("cbind.data.frame", lapply(df1, function(x) x[!is.na(x)]))
# a b
#1 10 4
#2 11 5
由于我们过滤了只有nlevels
个观察值的数据框,所以最终数据框中的每一列将具有相同数量的行。
答案 1 :(得分:2)
split
在这里可能有用,可以将df$v1
拆分为与df$f1
相对应的部分。由于您总是提取等长的块,因此可以将其简单地组合回data.frame
:
spl <- split(df$v1, df$f1)
data.frame(spl[lengths(spl)==2])
# a b
#1 10 4
#2 11 5
或者通过将其与Filter
组合在一起,一次完成所有操作:
data.frame(Filter(function(x) length(x)==2, split(df$v1, df$f1)))
# a b
#1 10 4
#2 11 5
答案 2 :(得分:1)
这是使用unstack
的解决方案:
unstack(
droplevels(df[ave(df$v1, df$f1, FUN = function(x) length(x) == 2)==1,]),
v1 ~ f1)
# a b
# 1 10 4
# 2 11 5
一个变种,类似于@thelatemail的解决方案:
data.frame(Filter(function(x) length(x) == 2, unstack(df,v1 ~ f1)))
我的 tidyverse
解决方案是:
library(tidyverse)
df %>%
group_by(f1) %>%
filter(n() == 2) %>%
mutate(i = row_number()) %>%
spread(f1, v1) %>%
select(-i)
# # A tibble: 2 x 2
# a b
# * <dbl> <dbl>
# 1 10 4
# 2 11 5
或混合方法:
as_tibble(keep(unstack(df,v1 ~ f1), ~length(.x) == 2))
答案 3 :(得分:0)
我想要这样的代码,可能对您有帮助
library(reshape2)
library(dplyr)
aa = data.frame(v1=c('a','a','b','b','c','c','c'),f1=c(10,11,4,5,0,1,2))
cc = aa %>% group_by(v1) %>% summarise(id = length((v1)))
dd= merge(aa,cc) #get the level
ee = dd[dd$aa==2,] #select number of level equal to 2
ee$id = rep(c(1,2),nrow(ee)/2) # reset index like (1,2,1,2)
dcast(ee, id~v1,value.var = 'f1')
全部完成!
答案 4 :(得分:0)
使用所有基本功能(但您应该使用tidyverse)
# Add count of instances
x$len <- ave(x$v1, x$f1, FUN = length)
# Filter, drop the count
x <- x[x$len==2, c('f1','v1')]
# Hacky pivot
result <- data.frame(
lapply(unique(x$f1), FUN = function(y) x$v1[x$f1==y])
)
colnames(result) <- unique(x$f1)
> result
a b
1 10 4
2 11 5