R 跨多个列应用函数
请在这里找到我正在使用的长data.table的一个非常小的子集R 跨多个列应用函数,r,data.table,R,Data.table,请在这里找到我正在使用的长data.table的一个非常小的子集 dput(dt) structure(list(id = 1:15, pnum = c(4298390L, 4298390L, 4298390L, 4298558L, 4298558L, 4298559L, 4298559L, 4299026L, 4299026L, 4299026L, 4299026L, 4300436L, 4300436L, 4303566L, 4303566L), invid = c(15
dput(dt)
structure(list(id = 1:15, pnum = c(4298390L, 4298390L, 4298390L,
4298558L, 4298558L, 4298559L, 4298559L, 4299026L, 4299026L, 4299026L,
4299026L, 4300436L, 4300436L, 4303566L, 4303566L), invid = c(15L,
101L, 102L, 103L, 104L, 103L, 104L, 106L, 107L, 108L, 109L, 87L,
111L, 2L, 60L), fid = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L,
4L, 4L, 4L, 4L, 3L, 3L, 2L, 2L), .Label = c("CORN", "DowCor",
"KIM", "Texas"), class = "factor"), dom_kn = c(1L, 0L, 0L, 0L,
1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L), prim_kn = c(1L,
0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L), pat_kn = c(1L,
0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L), net_kn = c(1L,
0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L), age_kn = c(1L,
0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L), legclaims = c(5L,
0L, 0L, 2L, 5L, 2L, 5L, 0L, 0L, 0L, 0L, 5L, 0L, 5L, 2L), n_inv = c(3L,
3L, 3L, 2L, 2L, 2L, 2L, 4L, 4L, 4L, 4L, 2L, 2L, 2L, 2L)), .Names = c("id",
"pnum", "invid", "fid", "dom_kn", "prim_kn", "pat_kn", "net_kn",
"age_kn", "legclaims", "n_inv"), class = "data.frame", row.names = c(NA,
-15L))
我希望在5个不同的列中应用调整后的大于比较
在每个pnum
(专利)中,都有多个invid
(发明人)。我想将每行dom_kn
、prim_kn
、pat_kn
、net_kn
和age_kn
列的值与其他行中具有相同pnum
的值进行比较。比较只是
,如果该值确实大于另一个值,则应归因于一个“点”
因此,对于第一行pnum==4298390
和invid==15
,您可以看到五列中的值都是1
,而invid==101 | 102
的值都是零。这意味着,如果我们单独比较(大于?)第一行中的每个值与第二行和第三行中的每个单元格,则总和将为10分。在每一次比较中,第一行中的值较大,有10次比较。
比较次数按设计5*(n\u inv-1)
。
我要查找的第1行的结果应该是10/10=1
对于pnum==4298558
而言,列net_kn
和age_kn
在两行中都有值1(对于invid
103和104),因此每个列都应该得到0.5分(如果有三个发明人的值为1,每个人都应该得到0.33分)。这同样适用于pnum==4298558
对于下一个pnum==4299026
所有值均为零,因此每次比较应得到0分
因此请注意差异:有三种不同的二元比较
1 > 0 --> assign 1
1 = 1 --> assign 1 / number of positive values in column subset
0 = 0 --> assign 0
期望的结果
数据表中的一个额外列result
,其值1 0 0 0.2 0.8 0.2 0.8 0 0 0 0 0 1 0.8 0.2
关于如何有效地计算这个问题,有什么建议吗
谢谢 这里有一个使用
dplyr
的快速解决方案:
library(dplyr)
dt %>%
group_by(pnum) %>% # group by pnum
mutate_each(funs(. == max(.) & max(.) != 0), ends_with('kn')) %>%
#give a 1 if the value is the max, and not 0. Only for the column with kn
mutate_each(funs(. / sum(.)) , ends_with('kn')) %>%
#correct for multiple maximums
select(ends_with('kn')) %>%
#remove all non kn columns
do(data.frame(x = rowSums(.[-1]), y = sum(.[-1]))) %>%
#make a new data frame with x = rowsums for each indvidual
# and y the colusums
mutate(out = x/y)
#divide by y (we could just use /5 if we always have five columns)
在列out
中给出所需的输出:
Source: local data frame [15 x 4]
Groups: pnum [6]
pnum x y out
(int) (dbl) (dbl) (dbl)
1 4298390 5 5 1.0
2 4298390 0 5 0.0
3 4298390 0 5 0.0
4 4298558 1 5 0.2
5 4298558 4 5 0.8
6 4298559 1 5 0.2
7 4298559 4 5 0.8
8 4299026 NaN NaN NaN
9 4299026 NaN NaN NaN
10 4299026 NaN NaN NaN
11 4299026 NaN NaN NaN
12 4300436 5 5 1.0
13 4300436 0 5 0.0
14 4303566 4 5 0.8
15 4303566 1 5 0.2
NAN来自没有赢家的组,使用例如:
x[is.na(x)] <- 0
x[is.na(x)]这里有一个使用dplyr的快速解决方案:
library(dplyr)
dt %>%
group_by(pnum) %>% # group by pnum
mutate_each(funs(. == max(.) & max(.) != 0), ends_with('kn')) %>%
#give a 1 if the value is the max, and not 0. Only for the column with kn
mutate_each(funs(. / sum(.)) , ends_with('kn')) %>%
#correct for multiple maximums
select(ends_with('kn')) %>%
#remove all non kn columns
do(data.frame(x = rowSums(.[-1]), y = sum(.[-1]))) %>%
#make a new data frame with x = rowsums for each indvidual
# and y the colusums
mutate(out = x/y)
#divide by y (we could just use /5 if we always have five columns)
在列out
中给出所需的输出:
Source: local data frame [15 x 4]
Groups: pnum [6]
pnum x y out
(int) (dbl) (dbl) (dbl)
1 4298390 5 5 1.0
2 4298390 0 5 0.0
3 4298390 0 5 0.0
4 4298558 1 5 0.2
5 4298558 4 5 0.8
6 4298559 1 5 0.2
7 4298559 4 5 0.8
8 4299026 NaN NaN NaN
9 4299026 NaN NaN NaN
10 4299026 NaN NaN NaN
11 4299026 NaN NaN NaN
12 4300436 5 5 1.0
13 4300436 0 5 0.0
14 4303566 4 5 0.8
15 4303566 1 5 0.2
NAN来自没有赢家的组,使用例如:
x[is.na(x)] <- 0
x[is.na(x)]
处理上述NaN
案例(可以说是正确的答案)由读者决定
处理上述NaN
案例(可以说是正确答案)留给读者。我不太清楚,因为pnum==4298558
,net_kn和age_kn都是1,所以没有一个大于另一个,根据您的描述,它们应该是0。为什么不是这样?描述可能不清楚。它们都有值1,需要与同样有值1的下一行进行比较。如果它们相等且为1,则应获得专利“比较简单>栏中正值数量的1/值,如果该值确实大于另一个值,则应归因于一个“点”。它们相等,所以它们得到0,为什么它们得到1?好的,我需要重新定义它。如果在同一列和同一专利中,多个值的值为1,则分配的值不为零。它必须是1除以非零值的数量。这些列只能取1或0?我不太清楚,因为pnum==4298558
,net_kn和age_kn都有1,所以没有一个大于另一个,根据您的描述,它们应该得到0。为什么不是这样?描述可能不清楚。它们都有值1,需要与同样有值1的下一行进行比较。如果它们相等且为1,则应获得专利“比较简单>栏中正值数量的1/值,如果该值确实大于另一个值,则应归因于一个“点”。它们相等,所以它们得到0,为什么它们得到1?好的,我需要重新定义它。如果在同一列和同一专利中,多个值的值为1,则分配的值不为零。它必须是1除以非零值的数量,这些列只能取1或0?这真是一个很棒的解决方案。我甚至不知道可以通过data.table
中的参数向添加列名。那太好了。同样非常出色的是,您成功地忽略了这个困难的解释,并意识到可以通过对列中的行进行求和来实现同样的效果。直到《蝙蝠侠与超人》的一半,我才意识到这一点!就我的理解而言,这里的.N
是否等于特定变量的列和,而不是行数的计数?如果是,这是因为您在by
语句中添加了'var
?再次感谢!很乐意帮忙.N
是“pnum”和给定“var”的每个唯一组合的行数。这真是一个很棒的解决方案。我甚至不知道可以通过data.table
中的参数向添加列名。那太好了。同样非常出色的是,您成功地忽略了这个困难的解释,并意识到可以通过对列中的行进行求和来实现同样的效果。直到《蝙蝠侠与超人》的一半,我才意识到这一点!就我的理解而言,这里的.N
是否等于特定变量的列和,而不是行数的计数?如果是,这是因为您在by
语句中添加了'var
?再次感谢!很乐意帮忙.N
是“pnum”和给定“var”的每个唯一组合的行数。