Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于将每行值更改为rowsum-1(其中值为1)的更快代码_R_Dataframe_Rowsum - Fatal编程技术网

用于将每行值更改为rowsum-1(其中值为1)的更快代码

用于将每行值更改为rowsum-1(其中值为1)的更快代码,r,dataframe,rowsum,R,Dataframe,Rowsum,在R中,我有一个带有采样位置和条目的大数据帧(23344行x 89列) 值1表示:在此采样位置找到的对象 值0表示:在此采样位置未找到对象 要计算每个采样位置(节点)的度数/连接数,我希望,每行,获取行和-1(因为这等于度数),并将该行中的1更改为该值。 此后,我可以获得colSum()来计算每个样本位置的总度数 我的数据帧的可复制示例: loc1 <- c(1,0,1) loc2 <- c(0,1,1) loc3 <- c(1,1,0) loc4 <- c(1,1,0)

在R中,我有一个带有采样位置和条目的大数据帧(23344行x 89列)

值1表示:在此采样位置找到的对象 值0表示:在此采样位置未找到对象

要计算每个采样位置(节点)的度数/连接数,我希望,每行,获取
行和-1
(因为这等于度数),并将该行中的1更改为该值。 此后,我可以获得
colSum()
来计算每个样本位置的总度数

我的数据帧的可复制示例:

loc1 <- c(1,0,1)
loc2 <- c(0,1,1)
loc3 <- c(1,1,0)
loc4 <- c(1,1,0)
loc5 <- c(0,1,0)
df <- data.frame(loc1, loc2, loc3, loc4, loc5)

#    loc1 loc2 loc3 loc4 loc5
# 1  1    0    1    1     0               
# 2  0    1    1    1     1 
# 3  1    1    0    0     0
我有可以工作的代码,但它很慢(包含for循环),所以有更好/更快的方法来实现这一点吗?我知道函数
rowSums()
,它可能是解决方案的一部分

我目前的代码如下:

for (r in 1:nrow(df)){
    df[r, df[r,] == 1] <- sum(df[r,]) - 1}

degrees_per_sample <- colSums(df)
for(1中的r:nrow(df)){

df[r,df[r,]==1]您可以尝试在数据帧上使用
ifelse()

df[] <- ifelse(df == 1, rowSums(df) - 1, 0)
您可以使用:

df[] <- +(df > 0) * (rowSums(df) - 1)
df

#  loc1 loc2 loc3 loc4 loc5
#1    2    0    2    2    0
#2    0    3    3    3    3
#3    1    1    0    0    0
df[]0)*(行和(df)-1)
df
#loc1 loc2 loc3 loc4 loc5
#1    2    0    2    2    0
#2    0    3    3    3    3
#3    1    1    0    0    0
认为,看到使用矩阵而不是data.frames来处理此类内容的好处可能会很有趣:

set.seed(1)
df = as.data.frame(matrix(rbinom(23344*89,1, 0.5), ncol=89))
m = as.matrix(df) # deliberately did the coercion outside the benchmark

all.equal(as.data.frame(ifelse(df == 1, rowSums(df) - 1, 0)), df* (rowSums(df) - 1))

microbenchmark::microbenchmark(
  a = {ifelse(df == 1, rowSums(df) - 1, 0)},
  b = {df* (rowSums(df) - 1)},
  c = {m* (rowSums(m) - 1)}
)
# Unit: milliseconds
#  expr       min        lq      mean   median        uq      max neval cld
#     a 112.29431 142.70233 165.39007 149.7674 157.63988 304.6195   100  b 
#     b 193.05255 222.24858 245.57206 228.2012 236.38952 402.2677   100   c
#     c  18.49041  26.92273  33.77159  27.3092  27.80769 181.4236   100 a  

**结果的类别存在差异,这将影响时间。

如果数据都是数字,则处理矩阵的速度更快。您可以执行
df*(行和(df)-1)
但是df是一个矩阵会更快这也行得通,谢谢,我接受了@Ronak Shah的回答,因为它只快了一点点。我以前没有使用微基准来比较计算时间,我的默认设置是在R中使用数据帧而不是矩阵,所以这个建议非常有用,将来会对我有所帮助。它确实是10倍f比使用数据帧更简单。复选标记与上面的答案保持一致,因为它节省了我强制df的步骤。
df[] <- +(df > 0) * (rowSums(df) - 1)
df

#  loc1 loc2 loc3 loc4 loc5
#1    2    0    2    2    0
#2    0    3    3    3    3
#3    1    1    0    0    0
set.seed(1)
df = as.data.frame(matrix(rbinom(23344*89,1, 0.5), ncol=89))
m = as.matrix(df) # deliberately did the coercion outside the benchmark

all.equal(as.data.frame(ifelse(df == 1, rowSums(df) - 1, 0)), df* (rowSums(df) - 1))

microbenchmark::microbenchmark(
  a = {ifelse(df == 1, rowSums(df) - 1, 0)},
  b = {df* (rowSums(df) - 1)},
  c = {m* (rowSums(m) - 1)}
)
# Unit: milliseconds
#  expr       min        lq      mean   median        uq      max neval cld
#     a 112.29431 142.70233 165.39007 149.7674 157.63988 304.6195   100  b 
#     b 193.05255 222.24858 245.57206 228.2012 236.38952 402.2677   100   c
#     c  18.49041  26.92273  33.77159  27.3092  27.80769 181.4236   100 a