我试图用R来做一些数据管理。
我有一个数据框,作为多个变量(+200列)和许多观察(+10,000行)。有大量缺失的数据,以及重复或未完成的观察。 一个观察应该等于一个人(1行= 1个独特的人)
这是数据集示例(感谢@aosmith):
dat = data.frame(email = c(rep(c("user1@hotmail.com", "user2@gmail.com"), each = 2), NA),
name = c(NA, "Alfred C.", NA, "Bob V.", "Cathy L."),
var1 = c(2, 2, NA, NA, 1),
var2 = c(1, NA, 3, NA, 1),
var3 = c(NA, NA, 1, 0, 2),
var4 = c(0, NA, NA, NA, NA))
我想合并我的观察结果,最后一行等于一个人。要识别我使用该电子邮件的人。当没有电子邮件时,我想保留所有观察结果(如果电子邮件遗失,我不希望R删除观察结果。每次观察都认为没有电子邮件被认为是一种独特的观察结果。)
对于我们可以发现相同电子邮件地址的时代,我们需要R来更新每个变量的字段,当数据丢失时,我们会在随后的观察结果(使用相同的电子邮件地址)中获得数据。如果已经有一个或多个变量的现有数据,我们希望R创建,每次都有一个新变量来存储不同的值。
这是一个让人们更容易理解的例子。
我们需要改变这样的事情:
email name var1 var2 var3 var4 ... var200
user1@hotmail.com <NA> 2 1 NA 0 ... .
user1@hotmail.com Alfred C. 2 NA NA NA ... .
user2@gmail.com <NA> NA 3 1 NA ... .
user2@gmail.com Bob V. NA NA 0 NA ... .
<NA> Cathy L. 1 1 2 NA ... .
进入这样的事情(将行与相同的电子邮件相结合,并将同一个人的所有信息保存在一行中,但也可以在我们无法识别该人与电子邮件地址相同时保留信息。所以,如果电子邮件是NA我们必须保持它好像是一个独特的人):
email name var1 var2 var3a var3b var4 ... var200
user1@hotmail.com Alfred C. 2 1 NA NA 0 . .
user2@gmail.com Bob V. NA 3 1 0 NA . .
<NA> Cathy L. 1 1 2 . NA . .
userX@email.com . . etc etc etc etc etc etc
有一种简单的方法吗?我和dplyr和tidyr挣扎了两天...... 最后,一行应包含我们能够使用电子邮件变量识别的一个人的信息。我们还需要保留我们无法识别属于一个人的所有其他观察结果。
感谢您的帮助和时间!
答案 0 :(得分:3)
我想出了一个选项,以防你不知道主题中每个变量有多少值。您将看到大多数步骤(为单独的列创建单独的名称)。
过程是使用gather
将数据集放入长格式,删除每个主题和变量组合的缺失值和重复值,为每个变量有多个值时创建变量名称(添加b,c等等到变量名称的末尾),然后用spread
将数据集放回宽格式。
dat = data.frame(email = rep(c("user1@hotmail.com", "user2@gmail.com"), each = 2),
twitter = c(NA, "user1", NA, "user2"),
var1 = c(2, 2, NA, NA),
var2 = c(1, NA, 3, NA),
var3 = c(NA, NA, 1, 0),
var4 = c(0, NA, NA, NA))
library(dplyr)
library(tidyr)
dat %>%
gather(allvar, value, twitter:var4) %>%
group_by(email, allvar) %>%
filter(!is.na(value) & !duplicated(value)) %>%
mutate(allvar2 = paste0(allvar, c("", letters[2:26])[1:n()])) %>%
ungroup() %>%
select(-allvar) %>%
spread(allvar2, value, convert = TRUE)
Source: local data frame [2 x 7]
email twitter var1 var2 var3 var3b var4
1 user1@hotmail.com user1 2 1 NA NA 0
2 user2@gmail.com user2 NA 3 1 0 NA
编辑以查找缺少某些电子邮件地址时的新示例
我不完全清楚你是否总是有Twitter或电子邮件信息或两者兼而有之 - 如果是这样的话,我认为可以通过在@ jazurro&#39中使用na.locf
来填充Twitter来简化这一过程。 ;回答并使用电子邮件和推特的组合作为分组变量。
要保留没有电子邮件的行,您可以将其过滤掉,执行所需的一切,然后rbind_list
将它们重新输入。在这种情况下,命名重复的变量,例如var3
和{{1将会为您解决(可以将它们命名为var3b
,var3a
,但不会为此rbinding方法工作。)
var3b