2015-09-08 29 views
3

我有我似乎无法一个问题找出R:相同的行组合成一个(优选使用dplyr/tidyr)

我有这样

df <- data.frame(c(rep_len("a",3), "b", "b"), c(rep_len(55, 3), 44, 44),c(rep_len(12, 3), 6, 6), c("na", 2, "na", 3, "na"), c("na", "na", 4, "na", 8), c(5, "na", "na", "na", "na")) 
names(df) <- c("street", "latitude", "longitude", "A", "B", "C") 

street latitude longitude  A B C 
    a  55   12 na na 5 
    a  55   12  2 na na 
    a  55   12 na 4 na 
    b  44   6  3 na na 
    b  44   6 na 8 na 

数据帧和我想我正在寻找的是崩溃与“街道”相同的价值观,“纬度”,“经度”行,所以数据帧看起来像这样

street latitude longitude  A B C 
    a  55  12  2 4 5 
    b  44   6  3 8 na 

我最好的尝试的方法是这样的:

df %>% 
    group_by(street) %>% 
    summarise_each(funs(first)) 

但它并不完全正确。有什么想法?

+2

一种方法是融化你的宽桌到一个长一个,删除NAs并将其投入一个广泛的。寻找* reshape2 *包或类似的。有些东西告诉我你可能会考虑重新设计你处理数据的方式。 – mlt

回答

1

此作品,未经改造和使用只是dplyr,只要你在的地方你"na"的使用标准NA并指定stringsAsFactors=FALSE创建df时:

df %>% 
    group_by(street, latitude, longitude) %>% 
    summarise_each(funs(ifelse(sum(is.na(.)==FALSE)==0, NA, .[which(is.na(.)==FALSE)])), matches("[A-Z]{1}")) 

# Result 
    street latitude longitude A B C 
1  a  55  12 2 4 5 
2  b  44   6 3 8 NA 

如果你喜欢坚持"na",那么这个工程:

df %>% 
    group_by(street, latitude, longitude) %>% 
    summarise_each(funs(ifelse(sum(.!="na")==0, "na", .[which(.!="na")])), matches("[A-Z]{1}")) 
+2

另一种选择是'summarise_each(funs(first(。[!is.na(。)]))'或'summarise_each(funs(。[。!=“na”] [1]))' – aosmith

+0

@aosmith这也是我如何做到的。 –

5

我不明白你为什么有"na"字符串 - R的字符/因子为NA。无论如何,你比如说,你正在寻找这样的:

library(data.table) 
dt = as.data.table(df) # or convert in place using setDT 

dt[, lapply(.SD, function(x) x[x != "na"]), by = .(street, latitude, longitude)] 
# street latitude longitude A B C 
#1:  a  55  12 2 4 5 
#2:  b  44   6 3 8 NA 
1

要在@ MLT的评论扩展,你可以使用tidyr(继任reshape2)重塑这一点。它看起来像

df %>% 
    gather(type, value, -c(street, latitude, longitude)) %>% 
    na.omit %>% 
    spread(type, value) 

这将A/B/C列扩展为行,省略NA字段,然后将其展开。

正如@eddi注意,你需要使用内置NA值,而不是字符串“NA”。我用

dfs <- 'street latitude longitude  A B C 
    a  55   12 NA NA 5 
    a  55   12  2 NA NA 
    a  55   12 NA 4 NA 
    b  44   6  3 NA NA 
    b  44   6 NA 8 NA 
' 
df <- read.table(text=dfs, header=T) 
相关问题