我有一个小的(2k)数据集,其中包含由学生填写的问卷答案,每年抽样两次。并非所有参加第一波的学生都参加了第二波,反之亦然。对于每个学生,创建了一个唯一的ID,其中包括学校代码,班级代码,学生编号和波形作为小数点。例如100612.1是名单上的10年级,6年级,12年级的学生,这是第一波。小数点后面的想法是一种在数据集中再次识别同一个学生的方法(与给定id相差不大于abs(1)的唯一值是另一个wave中的同一个学生)。至少这是想法。
我在考虑一个可以执行以下操作的脚本: - 找到彼此唯一id小于abs(1)的行 - 对于那些行,生成一个新行(在新表中),该行包括学生ID和测量变量的增量(即波2中的值 - 波1中的值)。
我是R的新手,但我在其他OOP中有一点点背景知识。我想创建一个从1到长度(df)的for循环,只是寻找它的“兄弟”。我的直觉告诉我,这不是R在任何想法中完成事情的方式吗? 我只需要快速筛选数据,寻找第二波浪行。我认为其余部分应该从那里直接进行。
谢谢你的帮助
PS。因为这是我在这里发表的第一篇文章,所以我事先为这篇文章中的任何错误道歉...... :)
答案 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.frame
和tapply
,您可以执行此操作:
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
语法,但现在我发现它更直观,并且对于大数据来说速度很快。