发现"几乎"复制数据表中的索引并计算增量

时间:2014-12-04 19:44:49

标签: r

我有一个小的(2k)数据集,其中包含由学生填写的问卷答案,每年抽样两次。并非所有参加第一波的学生都参加了第二波,反之亦然。对于每个学生,创建了一个唯一的ID,其中包括学校代码,班级代码,学生编号和波形作为小数点。例如100612.1是名单上的10年级,6年级,12年级的学生,这是第一波。小数点后面的想法是一种在数据集中再次识别同一个学生的方法(与给定id相差不大于abs(1)的唯一值是另一个wave中的同一个学生)。至少这是想法。

我在考虑一个可以执行以下操作的脚本: - 找到彼此唯一id小于abs(1)的行 - 对于那些行,生成一个新行(在新表中),该行包括学生ID和测量变量的增量(即波2中的值 - 波1中的值)。

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

谢谢你的帮助

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

3 个答案:

答案 0 :(得分:0)

有两种方式可以想到。最简单的方法是使用函数floor(),它返回整数,例如:

floor(100612.1)
#[1] 100612

floor(9.9)
#[1] 9

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

答案 1 :(得分: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)

现在让我们将ID分成两个不同的列:

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

然后我们按照孩子和wave的顺序排序,并根据孩子计算差异:

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

答案 2 :(得分: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.frametapply,您可以执行此操作:

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

删除delta值为NA的行:

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仅输出特定列(除了by列),例如

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

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