我正在处理R中相当大的数据集,该数据集分为几个数据帧。
问题是我用整套做了一些事情,有时我只需要处理或修改集合的部分,我的选择器变得非常笨重,等等。
aListOfItems$attribute4([aListOfItems$attribute1 == true & aListOfItems$attribute2 == 6
& aListOfItems$attribute3 == "C"),] <- aListOfItems([aListOfItems$attribute1 == true &
aListOfItems$attribute2 == 6 & aListOfItems$attribute3 == "C"),aListOfItems$attribute5]
* aListOfItems([aListOfItems$attribute1 == true & aListOfItems$attribute2 == 6 &
aListOfItems$attribute3 == "C"),aListOfItems$attribute7]
(这会将属性4设置为(attribute5 * attribute6)所有条目的所选部分。)
阅读,理解和编辑是非常糟糕的。
由于RAM而将这些分成不同的数据帧并不是真正的选择,因为我会定期刷新这些数据并重建所有单独的数据帧也会很痛苦。
那么,有没有办法像
那样做items_t6C <- &(aListOfItems([aListOfItems$attribute1 == true & aListOfItems$attribute2
== 6 & aListOfItems$attribute3 == "C"),]
所以我可以使用
items_t6C$attribute4 <- # do something
或者,也许可以将这样的选择器存储在字符串变量中并使用它?
答案 0 :(得分:7)
您可以先构造一个逻辑向量,为其指定一个有意义的名称,然后在命令中使用它。它使您的脚本更长一点,但更容易阅读:
interesting_bit = with(aListOfItems, attribute1 &
attribute2 == 6 &
attribute3 == "C")
此外,使用一些缩进也可以使代码更具可读性。
aListOfItems$attribute4[interesting_bit,] <-
aListOfItems[interesting_bit,aListOfItems$attribute5]
* aListOfItems[interesting_bit,aListOfItems$attribute7]
使用within
可以提高可读性:
aListOfItems[interesting_bit,] = within(aListOfItems[interesting_bit,], {
attribute4 = attribute5 * attribute7
}
此外,对于逻辑,不需要显式测试== true
:
interesting_bit = aListOfItems$attribute1 &
aListOfItems$attribute2 == 6 & aListOfItems$attribute3 == "C"
这最终减少了这个:
aListOfItems$attribute4([aListOfItems$attribute1 == true & aListOfItems$attribute2 == 6
& aListOfItems$attribute3 == "C"),] <- aListOfItems([aListOfItems$attribute1 == true &
aListOfItems$attribute2 == 6 & aListOfItems$attribute3 == "C"),aListOfItems$attribute5]
* aListOfItems([aListOfItems$attribute1 == true & aListOfItems$attribute2 == 6 &
aListOfItems$attribute3 == "C"),aListOfItems$attribute7]
到此(注意with
的额外用法):
interesting_bit = with(aListOfItems, attribute1 &
attribute2 == 6 &
attribute3 == "C")
aListOfItems[interesting_bit,] = within(aListOfItems[interesting_bit,], {
attribute4 = attribute5 * attribute7
}
这段代码不仅看起来不那么令人生畏,而且还能立即传达出你正在做的事情,这很难与原始代码相提并论。
答案 1 :(得分:2)
data.table
包可能对您有用。
data.table
主要通过引用工作。特别是在分配和修改列时。
特别是如果你达到RAM限制,data.table的效率是戏剧性的
此外,data.table内置于with
within
by
subset
等功能中,使调用更短,代码更具可读性。
例如,上面的cummbersome语句可以简化为:
aDTofItems[attribute1 & attribute2==6 & attribute3=="C", # filter
attribute4 := attribute5 * attribute6] # assign
此外,如果您要过滤的属性是表格的key
,那么该行甚至更短:
aDTofItems[.(TRUE, 6, "C"), # filter
attribute4 := attribute5 * attribute6] # assign
假设每个元素的结构具有可比性,您可以使用
将列表强制转换为data.tableaDTofItems <- rbindlist(aListOfItems)
# note, if you have factors in your list you should convert them to character before calling rbindlist
# or similarly, although a bit slower
aDTofItems <- data.table(do.call(rbind, aListOfItems))