我在下面有一个示例数据框。我试图获取3行的每个序列并将第一个除以第3个(或者换句话说,对于每个id,将类“a”除以类“c”)。最简单的方法是什么?提前致谢。
$count = intval(file_get_contents("p.txt"));
file_put_contents("p.txt",++$count);
答案 0 :(得分:2)
您可以使用by
按 ID 分组,然后使用值和类进行分组:
by(data = data, INDICES = data$id,
FUN = function(ds) ds[ds$class == "a", "value"] /
ds[ds$class == "c", "value"])
这将为每个 id 生成一个值。输出:
data$id: 0
[1] 0.6885714
-----------------------------------------------------------------------------------------
data$id: 40
[1] 0.5989975
------------------------------------------------------------------------------------------
data$id: 53
[1] 0.6196078
------------------------------------------------------------------------------------------
data$id: 54
[1] 0.7539432
答案 1 :(得分:1)
我们可以尝试使用split
中的unsplit
/ base R
。通过“id”列split
数据集获取“列表”输出,通过添加新列('value1)在lapply
,transform
data.frame列表元素的列表中循环')基于将'class'('a'和'c')对应的'value'和{id'列的unsplit
分开。
unsplit(lapply(split(df1, df1$id), function(x)
transform(x, value1= value[class=='a']/value[class=='c'])), df1$id)
# id class value value1
#1 0 a 241 0.6885714
#2 0 b 109 0.6885714
#3 0 c 350 0.6885714
#4 40 a 239 0.5989975
#5 40 b 160 0.5989975
#6 40 c 399 0.5989975
#7 53 a 158 0.6196078
#8 53 b 97 0.6196078
#9 53 c 255 0.6196078
#10 54 a 239 0.7539432
#11 54 b 78 0.7539432
#12 54 c 317 0.7539432
或者使用mutate
中的dplyr
在按“ID”列分组后创建新列
library(dplyr)
df1 %>%
group_by(id) %>%
mutate(value1= value[class=='a']/value[class=='c'])
# id class value value1
#1 0 a 241 0.6885714
#2 0 b 109 0.6885714
#3 0 c 350 0.6885714
#4 40 a 239 0.5989975
#5 40 b 160 0.5989975
#6 40 c 399 0.5989975
#7 53 a 158 0.6196078
#8 53 b 97 0.6196078
#9 53 c 255 0.6196078
#10 54 a 239 0.7539432
#11 54 b 78 0.7539432
#12 54 c 317 0.7539432
或者如果它基于位置,即第一个和最后一个,您可以通过
更改上面代码中的最后一行 mutate(value1=first(value)/last(value))
或者紧凑的方法是使用data.table
。 :=
运算符在创建'value1'列时速度非常快。将“data.frame”更改为“data.table”(setDT(df1)
),创建按“id”分组的“value1”列。在这里,我选择了'值'的第一个(1L
)和最后一个观察(.N
),假设'a'和'c'是有序的。如果没有订购,请像以前一样使用value[class=='a']/value[class=='c']
。
library(data.table)
setDT(df1)[, value1:=value[1L]/value[.N] , id]
# id class value value1
#1: 0 a 241 0.6885714
#2: 0 b 109 0.6885714
#3: 0 c 350 0.6885714
#4: 40 a 239 0.5989975
#5: 40 b 160 0.5989975
#6: 40 c 399 0.5989975
#7: 53 a 158 0.6196078
#8: 53 b 97 0.6196078
#9: 53 c 255 0.6196078
#10:54 a 239 0.7539432
#11:54 b 78 0.7539432
#12:54 c 317 0.7539432
使用base R
的另一种方法。虽然,这项工作在示例数据集上,但它可能不适用于未订购数据的情况。
df1$value1 <- (df1$value[df1$class=='a']/
df1$value[df1$class=='c'])[as.numeric(factor(df1$id))]
如果您需要为每个ID设置一个值,请将mutate
替换为summarise
中的dplyr
df1 %>%
group_by(id) %>%
summarise(value1= value[class=='a']/value[class=='c'])
# id value1
#1 0 0.6885714
#2 40 0.5989975
#3 53 0.6196078
#4 54 0.7539432
或删除:=
data.table
)
setDT(df1)[, list(value1=value[class=='a']/value[class=='c']), id]
# id value1
#1: 0 0.6885714
#2: 40 0.5989975
#3: 53 0.6196078
#4: 54 0.7539432
df1 <- structure(list(id = c(0L, 0L, 0L, 40L, 40L, 40L, 53L, 53L, 53L,
54L, 54L, 54L), class = c("a", "b", "c", "a", "b", "c", "a",
"b", "c", "a", "b", "c"), value = c(241L, 109L, 350L, 239L, 160L,
399L, 158L, 97L, 255L, 239L, 78L, 317L)), .Names = c("id", "class",
"value"), class = "data.frame", row.names = c(NA, -12L))