2014-12-04 26 views
0

我有一个小样本(2k)数据集,其中包含由学生填写的问卷答案,每年抽样两次。并不是所有第一波的在场学生都在第二波,反之亦然。为每个学生创建一个由学校代码,班级代码,学号和波形组成的唯一ID作为小数点。例如100612.1是来自名单10和6,12年级的学生,这是第一波。小数点后面的想法是一种在数据集中再次识别同一个学生的方法(唯一的值小于abs(1)与给定的id是同一个学生在另一个wave上)。至少是理念。找到“几乎”重复数据表中的指数并计算增量

我在想一个脚本,会做以下: - 找到谁的唯一ID的行小于ABS(1)彼此 - 为那些行,生成一个新的行(新表)包括学生ID和测量变量的增量(即波形2中的值 - 波形1中的值)。

我是一个新的R,但我在其他OOP有一点背景。我想创建一个从1到长(df)的for循环,只是寻找它的“兄弟”。我的直觉告诉我,这不是在R中完成任何想法的方式吗? 我所需要的是通过查找第二个波浪行的数据筛选的快速方法。我认为其余的应该从那里直接前进。

感谢您的帮助

PS。因为这是我在这里的第一篇文章,我事前道歉在这篇文章中的任何错误...... :)

+0

切掉小数点,并通过剩余的id(100612) – rawr 2014-12-04 21:23:30

回答

0

这个问题提到data.table,所以这里有一个方法来修改@jed的答案。

ids <- c(100612.1,100612.2,100613.1,100613.2,110714.1,201802.2) 
answers <- c(5,4,3,4,1,0) 

示例数据和以前一样,现在的data.frame,而是tapply你可以这样做:

unique(surveyDT[, .SD[(!is.na(delta))], by = child]) 
    child  ids answers wave delta 
1: 100612 100612.1  5 1 -1 
2: 100613 100613.1  3 1  1 

使用.SDcols输出:

library(data.table) 

surveyDT <- data.table(ids, answers) 

surveyDT[, `:=` (child = substr(ids, 1, 6), wave = substr(ids, 8, 8))] # split ID's 
# note multiple assign-by-reference := syntax above 
setkey(surveyDT, child, wave) # order data 

# calculate delta on keyed data, grouping by child 
surveyDT[, delta := diff(answers), by = child] 

unique(surveyDT[, delta, by = child]) # list results 
    child delta 
1: 100612 -1 
2: 100613  1 
3: 110714 NA 
4: 201802 NA 

要与NA要delta值删除行只有特定列(除了by列以外),例如,

unique(surveyDT[, .SD[(!is.na(delta))], by = child, .SDcols = 'delta']) 
    child delta 
1: 100612 -1 
2: 100613  1 

我花了一些时间熟悉data.table的语法,但现在我发现它更直观,对于大数据来说它很快。

+0

谢谢!快速跟进问题,如果你不介意: - 没有必要的substr,因为我可以创建的孩子ID不使用波。我对么? - 如果我必须减去多个列,我可以一次计算所有内容吗? surveyDT [,delta1:= diff(answers),delta2:= diff(answers2),by = child]沿着这些线? - 是否有办法过滤出没有两个波的结果?我正在考虑使用complete.cases ..再次, ,谢谢! – isomitzi 2014-12-06 15:41:06

+0

如果您在问题中发布数据集的示例,这些类型的问题将更容易回答。 – jed 2014-12-08 15:45:04

+0

'complete.cases'可以在这里工作,但是请注意,它会删除任何列中具有NA的行。请参阅已编辑的答案,以便从特定列中筛选NA。回复:多列计算,按照我在示例中如何使用':='带反引号来分配子和波。有关更多信息,请参阅help(':=')'。 – Scott 2014-12-09 17:57:16

0

有两种方式,想到。最简单的是使用功能地板(),它返回整数例如:

floor(100612.1) 
#[1] 100612 

floor(9.9) 
#[1] 9 

或者,你可以写一个相当简单的正则表达式表达摆脱小数位的了。然后,您可以使用unique()来查找是否有重复条目的行。

0

让我们做一些假的数据,所以我们可以看到我们的问题很容易:

ids <- c(100612.1,100612.2,100613.1,100613.2,110714.1,201802.2) 
answers <- c(5,4,3,4,1,0) 
survey <- data.frame(ids,answers) 

现在,让我们的IDS分为两个不同的列:

survey$child_id <- substr(survey$ids,1,6) 
survey$wave_id <- substr(survey$ids,8,8) 

然后,我们将通过儿童和波订购,并根据孩子计算差异:

survey[order(survey$child_id, survey$wave_id),] 
survey$delta <- unlist(tapply(survey$answers, survey$child_id, function(x) c(NA,diff(x)))) 

输出:

 ids answers child_id wave_id delta 
1 100612.1  5 100612  1 NA 
2 100612.2  4 100612  2 -1 
3 100613.1  3 100613  1 NA 
4 100613.2  4 100613  2  1 
5 110714.1  1 110714  1 NA 
6 201802.2  0 201802  2 NA 
+0

来计算汇总统计量(即delta)谢谢! 我运行R中的代码来跟随。所提到的唯一ID是从数据中的现有变量创建的。即我有一个“波”变量。现在我看到你的建议了,是不是将一个键设置为“child,wave”也会这样做?另外,你最后的代码对我来说有点模糊...... 再次感谢你的快速重播!那些是伟大的想法。 – isomitzi 2014-12-05 01:20:29

+0

@isomitzi我所做的最后一段代码是... 如果一个孩子在两个波中都有答案,我从第二个波的分数中减去第一个波的分数。所以孩子100612在波1中有5个,在波2中有4个,所以他的三角洲是-1。 – jed 2014-12-05 17:36:55