簡體   English   中英

如何根據R中其他列中的值添加計數列

[英]How to add a counting column based on values in other columns in R

我有一個相對較大的數據集(16,000+ x ~31)。 換句話說,它足夠大,我不想在 Excel 中逐行操作它。 數據格式如下:

block  site     day  X1   X2
1      1        1    0.4  5.1 
1      1        2    0.8  1.1
1      1        3    1.1  4.2
1      2        1    ...  ...
1      2        2
1      2        3
2      3        1
2      3        2
2      3        3
2      4        1
2      4        2
2      4        3

如您所見,站點計數是連續的,但我想要一個列,其中站點編號隨每個塊重置。 例如,我想要以下內容:

block  site     day  X1   X2    site2
1      1        1    0.4  5.1   1
1      1        2    0.8  1.1   1
1      1        3    1.1  4.2   1
1      2        1    ...  ...   2
1      2        2               2
1      2        3               2
2      3        1               1
2      3        2               1
2      3        3               1
2      4        1               2
2      4        2               2
2      4        3               2

我正在考慮使用 R 函數 rle 但我不確定它是否會因為白天的並發症而起作用。 否則,我會嘗試類似的事情:

Data$site2 <- sequence(rle(Data$block)$lengths)

有沒有人對添加一個列計數(序列)每個塊內的站點數量有任何建議? 如果有幫助,每個站點記錄的天數 (263) 相同,但每個塊的站點數不同。

這是一個使用plyrddply的稍微笨拙的解決方案:

ddply(df,.(block),transform,
                  site1 = rep(1:length(unique(site)),
                             times = rle(site)$lengths))

或者一個稍微光滑的版本:

ddply(df,.(block),transform,site1 = as.integer(as.factor(site)))

不過,可能有一種聰明的方法可以直接執行此操作,使用各種seqsequencerle函數,但此刻我的大腦有點模糊。 如果您將其保持開放一段時間,那么可能會有人提出一種光滑的非plyr解決方案。

使用 tapply 可以工作

# Make some fake data
dat <- data.frame(block = rep(1:3, each = 4), site = rep(1:6, each  = 2), val = rnorm(12))
# For each block reset the count
dat$site2 <- unlist(tapply(dat$site, dat$block, function(x){x - min(x) + 1}))

我只是想更新一個答案,使用 dplyr 為現在找到這個的人實現@joran 的方法。

library(dplyr)

# create data
df <- data.frame(block = rep(1:3, each = 4), 
                 site = rep(1:6, each  = 2), 
                 day = rep(1:2, times = 6), 
                 x = rnorm(12))

df %>%
  group_by(block) %>%
  mutate(site2 = as.integer(as.factor(site)))

結果輸出是:

block  site   day     x    site2
<int> <int> <int>  <dbl>   <int>
1     1       1    0.762     1
1     1       2   -0.612     1
1     2       1    1.06      2
1     2       2   -0.168     2
2     3       1    1.09      1
2     3       2    1.38      1
2     4       1    1.69      2
2     4       2    0.414     2
3     5       1    0.208     1
3     5       2   -0.647     1
3     6       1   -1.01      2
3     6       2   -0.354     2

通過大街:

df1 <- structure(list(block = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2), 
    site = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4), day = c(1, 
    2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)), .Names = c("block", "site", 
"day"), row.names = c("2", "3", "4", "5", "6", "7", "8", "9", 
"10", "11", "12", "13"), class = "data.frame")

df1$site2 <- ave(df1$site,df1$block,FUN=function(x) match(x,sort(unique(x))))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM