R删除第一行和最后一行x%

时间:2017-10-03 14:20:58

标签: r

我有一个包含3个ID变量的数据框,然后是每个ID的几个值。

user   Log Pass  Value
2       2   123     342
2       2   123     543
2       2   123     231
2       2   124     257
2       2   124     342
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     342
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     543
4       3   125     231
4       3   125     257

每组值的开始和结束有时会产生噪音,我希望能够删除前几个值。不幸的是,值的数量变化很大,但它始终是噪声值的第一个和最后20%。

我想删除前20%的行,删除最少1行。

因此,例如,如果用户2 log 2传递123有20个值,我想删除第一行和最后4行。如果ID变量只有3个值,我想删除第一行和最后一行。

结果数据集为:

user   Log Pass  Value
2       2   123     543
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     543
4       3   125     231
4       3   125     257
4       3   125     543
4       3   125     231

我试过用nrow摆弄,但我很难弄清楚如何通过id变量引用行数百分比。

感谢。

乔纳森。

5 个答案:

答案 0 :(得分:2)

我相信以下可以做到。

数据。

    [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Login(string username, string password, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var claimsPrinciple = await _userService.GetUserAsync(username, password);

            if (claimsPrinciple == null)
            {
                ViewData["ReturnUrl"] = returnUrl;
                ModelState.AddModelError("Login", "Username or password is incorrect.");
                return View();
            };

            await HttpContext.SignInAsync(
                claimsPrinciple,
                new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = DateTime.UtcNow.AddDays(30),
                }
            );

            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
        }

        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

<强> CODE。

public partial class Migration_DistributedCache : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(@"CREATE TABLE [dbo].[DistributedCache] (
                                   [Id]                         NVARCHAR (449)     COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
                                   [Value]                      VARBINARY (MAX)    NOT NULL,
                                   [ExpiresAtTime]              DATETIMEOFFSET (7) NOT NULL,
                                   [SlidingExpirationInSeconds] BIGINT             NULL,
                                   [AbsoluteExpiration]         DATETIMEOFFSET (7) NULL,
                                   PRIMARY KEY CLUSTERED ([Id] ASC)
                               );


                               GO
                               CREATE NONCLUSTERED INDEX [Index_ExpiresAtTime]
                                   ON [dbo].[DistributedCache]([ExpiresAtTime] ASC);");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "Index_ExpiresAtTime",
            table: "DistributedCache");

        migrationBuilder.DropTable(
            name: "DistributedCache");
    }
}

答案 1 :(得分:2)

这样的事情有帮助吗?

对于数据框df

df[-c(1:floor(nrow(df)*0.2), (1+ceiling(nrow(df)*0.8)):nrow(df)),]

只删除第一个和最后一个20%,取上限和下限值,以便在较小的数据框中保留一些信息:

> df<-data.frame(a=1:100)
> df[-c(1:floor(nrow(df)*0.2),(1+ceiling(nrow(df)*0.8)):nrow(df)),]

 [1] 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
[31] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80


> df<-data.frame(1:3)
> df[-c(1:floor(nrow(df)*0.2),(1+ceiling(nrow(df)*0.8)):nrow(df)),]

[1] 2

答案 2 :(得分:1)

您可以使用dplyr ...

执行此操作
library(dplyr)
df2 <- df %>% group_by(user, Log, Pass) %>% 
  filter(n()>2) %>% #remove those with just two elements or fewer
  slice(max(2, 1+ceiling(n()*0.2)):min(n()-1, floor(0.8*n())))

df2
   user   Log  Pass Value
1     2     2   123   543
2     4     3   125   543
3     4     3   125   231
4     4     3   125   257
5     4     3   125   543
6     4     3   125   231
7     4     3   125   257
8     4     3   125   543
9     4     3   125   231

答案 3 :(得分:1)

这是一个使用基数R的想法,它返回每个用户的行索引,然后保留这些索引的子集。

idx <- unlist(lapply(split(seq_along(dat[["user"]]), dat[["user"]]), function(x) {
                     tmp <- max(1, ceiling(.2 * length(x)))
                     tail(head(x, -tmp), -tmp)}),
              use.names=FALSE)

split(seq_along(dat[["user"]]), dat[["user"]])返回每个用户的行列表。 lapply循环遍历这些行,使用split(seq_along(dat[["user"]]), dat[["user"]])计算要从每一端删除的行数,然后使用tail(head(x, -tmp), -tmp)})删除它们。由于lapply返回一个命名列表,因此该列表不公开,名称将被删除。

返回

idx
 2  3  4 10 11 12 13 14 15 16 17 

现在是子集

dat[idx,]
   user Log Pass Value
2     2   2  123   543
3     2   2  123   231
4     2   2  124   257
10    4   3  125   543
11    4   3  125   231
12    4   3  125   257
13    4   3  125   543
14    4   3  125   231
15    4   3  125   257
16    4   3  125   543
17    4   3  125   231

答案 4 :(得分:1)

计算您想要保留的偏移量:

rem <- ceiling( nrow( x ) * .2 ) + 1

然后取出你不想要的记录:

dat <- dat[ rem : ( nrow( dat ) - rem ), ]