R:将相同的行合并为一行(最好使用dplyr/tidyr)

R:将相同的行合并为一行(最好使用dplyr/tidyr),r,dplyr,tidyr,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", "

我有个问题,我似乎想不出来

我有一个这样的数据框

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))

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

我不明白为什么你有
“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

要扩展@mlt的注释,可以使用
tidyr
(重塑2的后续版本)来重塑此注释。看起来像

df %>%
  gather(type, value, -c(street, latitude, longitude)) %>%
  na.omit %>%
  spread(type, value)
这会将A/B/C列展开成行,省略NA字段,然后将其展开

正如@eddi所指出的,您需要使用内置的
NA
值,而不是字符串“NA”。我曾经


dfs只要在创建
df
时使用标准的
NA
代替
“NA”
,并指定
stringsAsFactors=FALSE
,则此操作无需重新整形,只需使用
dplyr

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}"))

一种方法是将宽表融化为长表,移除NAs并将其转换为宽表。寻找2号包装或类似产品。有些事情告诉我,你可能会考虑重新设计你处理数据的方式。另一种选择是类似于<代码> SimuleSeEX(Funs(第一个(.[..N.])))或<代码> SCORISISEAY每个(Funs(.[O.= Na)](1))< /代码> @ AOSMITH,我也是这样做的。
df %>%
  group_by(street, latitude, longitude) %>%
  summarise_each(funs(ifelse(sum(.!="na")==0, "na", .[which(.!="na")])), matches("[A-Z]{1}"))