根据条件从 data.frame 中删除行
Delete row from data.frame based on condition
我在 R
中尝试清理一些重复测量数据。在这一点上,它是长格式的,我试图在转向宽格式之前修复一些条目——例如,如果人们参加我的调查太多次,我将删除这些行。我有两个要解决的主要问题:
更改条目
如果有人在“预测试 link”中进行了调查,而实际上它应该是 post-测试,我将使用以下代码修复它:
data[data$UserID == 52118254, "Prepost"][2] <- 2
这会根据 ID 过滤掉那个人的条目,然后将第二个条目更改为编码为 post-测试。此代码具有足够的含义,查看它可以告诉我发生了什么。
掉一行
我正在努力获取有意义的代码来删除额外的行 - 例如,如果有人不小心点击了我的 link 两次。我有如下数据:
UserID Prepost Duration..in.seconds.
1 52118250 1 357
2 52118284 1 226
3 52118284 1 11 #This is an extra attempt to remove
4 52118250 2 261
5 52118284 2 151
#to reproduce:
structure(list(UserID = c(52118250, 52118284, 52118284, 52118250, 52118284), Prepost = c("1", "1", "1", "2", "2"), Duration..in.seconds. = c("357", "226", "11", "261", "151")), class = "data.frame", row.names = c(NA, -5L), .Names = c("UserID", "Prepost", "Duration..in.seconds."))
我可以按 UserID 进行过滤,以查看谁使用了它太多次,并且我正在寻找一种方法来轻松地从数据集中删除这些行。在这种情况下,UserID 52118284 已经尝试了三次,第二次尝试需要删除。如果它像其他修复程序一样“可读”,那就更好了。
我会使用一组 dplyr 函数,如下所示。解释一下:
group_by(UserID)
将有助于将功能分别应用到每个用户。
mutate(click_n = row_number())
迭代计算用户出现次数并将其保存为新变量 click_n
.
library(dplyr)
data %>%
group_by(UserID) %>%
mutate(click_n = row_number())
#> Source: local data frame [5 x 4]
#> Groups: UserID [4]
#>
#> UserID Prepost Duration..in.seconds. click_n
#> <dbl> <chr> <chr> <int>
#> 1 52118254 1 357 1
#> 2 52118284 1 226 1
#> 3 52118284 1 11 2
#> 4 52118250 2 261 1
#> 5 52118280 2 151 1
filter(click_n == 1)
可用于仅保留第一次尝试,如下所示。
data <- data %>%
group_by(UserID) %>%
mutate(click_n = row_number()) %>%
filter(click_n == 1)
data
#> Source: local data frame [4 x 4]
#> Groups: UserID [4]
#>
#> UserID Prepost Duration..in.seconds. click_n
#> <dbl> <chr> <chr> <int>
#> 1 52118254 1 357 1
#> 2 52118284 1 226 1
#> 3 52118250 2 261 1
#> 4 52118280 2 151 1
请注意,此方法假定您的数据框是有序的。即,第一次点击出现在顶部附近。
如果您不熟悉 %>%
,请在 "pipe operator" 上寻求帮助。
额外:
要将评论变成答案,一旦您对这里发生的事情感到满意,您可以跳过 mutate
行,只需执行以下操作:
data %>% group_by(UserID) %>% filter(row_number() == 1)
下面是删除重复项的简单解决方案:
subset(data, !duplicated(data$UserID))
但是,您可能还需要考虑按持续时间进行子集化,例如,如果持续时间少于 30 秒。
感谢@Simon 的建议。我想要的一个标准是代码有意义,因为我 "read" 它。正如我所想的那样,另一个标准是我想仔细考虑要进行哪些更改。所以我采纳了 Simon 的建议,单独列了一个专栏,然后使用 dplyr::filter()
来排除那些变量。下面是一段示例代码:
#Change pre/post entries
data[data$UserID == 52118254, "Prepost"][2] <- 2
#Mark rows to delete
data$toDelete <- NA #Makes new empty column for marking deletions
data[data$UserID == 52118284,][2, "toDelete"] <- 1 #Marks row for deletion
#Filter to exclude rows
data %>% filter(is.na(toDelete))
#Optionally add "%>% select(-toDelete)" to remove the extra column
在我的上下文中,这里的优点是一切都是故意的而不是自动的,并且更改锚定到数据而不是可能更改的行号。我仍然欢迎任何反馈或其他实现此目的的方法(也许只需一步)。
我在 R
中尝试清理一些重复测量数据。在这一点上,它是长格式的,我试图在转向宽格式之前修复一些条目——例如,如果人们参加我的调查太多次,我将删除这些行。我有两个要解决的主要问题:
更改条目
如果有人在“预测试 link”中进行了调查,而实际上它应该是 post-测试,我将使用以下代码修复它:
data[data$UserID == 52118254, "Prepost"][2] <- 2
这会根据 ID 过滤掉那个人的条目,然后将第二个条目更改为编码为 post-测试。此代码具有足够的含义,查看它可以告诉我发生了什么。
掉一行
我正在努力获取有意义的代码来删除额外的行 - 例如,如果有人不小心点击了我的 link 两次。我有如下数据:
UserID Prepost Duration..in.seconds.
1 52118250 1 357
2 52118284 1 226
3 52118284 1 11 #This is an extra attempt to remove
4 52118250 2 261
5 52118284 2 151
#to reproduce:
structure(list(UserID = c(52118250, 52118284, 52118284, 52118250, 52118284), Prepost = c("1", "1", "1", "2", "2"), Duration..in.seconds. = c("357", "226", "11", "261", "151")), class = "data.frame", row.names = c(NA, -5L), .Names = c("UserID", "Prepost", "Duration..in.seconds."))
我可以按 UserID 进行过滤,以查看谁使用了它太多次,并且我正在寻找一种方法来轻松地从数据集中删除这些行。在这种情况下,UserID 52118284 已经尝试了三次,第二次尝试需要删除。如果它像其他修复程序一样“可读”,那就更好了。
我会使用一组 dplyr 函数,如下所示。解释一下:
group_by(UserID)
将有助于将功能分别应用到每个用户。
mutate(click_n = row_number())
迭代计算用户出现次数并将其保存为新变量 click_n
.
library(dplyr)
data %>%
group_by(UserID) %>%
mutate(click_n = row_number())
#> Source: local data frame [5 x 4]
#> Groups: UserID [4]
#>
#> UserID Prepost Duration..in.seconds. click_n
#> <dbl> <chr> <chr> <int>
#> 1 52118254 1 357 1
#> 2 52118284 1 226 1
#> 3 52118284 1 11 2
#> 4 52118250 2 261 1
#> 5 52118280 2 151 1
filter(click_n == 1)
可用于仅保留第一次尝试,如下所示。
data <- data %>%
group_by(UserID) %>%
mutate(click_n = row_number()) %>%
filter(click_n == 1)
data
#> Source: local data frame [4 x 4]
#> Groups: UserID [4]
#>
#> UserID Prepost Duration..in.seconds. click_n
#> <dbl> <chr> <chr> <int>
#> 1 52118254 1 357 1
#> 2 52118284 1 226 1
#> 3 52118250 2 261 1
#> 4 52118280 2 151 1
请注意,此方法假定您的数据框是有序的。即,第一次点击出现在顶部附近。
如果您不熟悉 %>%
,请在 "pipe operator" 上寻求帮助。
额外:
要将评论变成答案,一旦您对这里发生的事情感到满意,您可以跳过 mutate
行,只需执行以下操作:
data %>% group_by(UserID) %>% filter(row_number() == 1)
下面是删除重复项的简单解决方案:
subset(data, !duplicated(data$UserID))
但是,您可能还需要考虑按持续时间进行子集化,例如,如果持续时间少于 30 秒。
感谢@Simon 的建议。我想要的一个标准是代码有意义,因为我 "read" 它。正如我所想的那样,另一个标准是我想仔细考虑要进行哪些更改。所以我采纳了 Simon 的建议,单独列了一个专栏,然后使用 dplyr::filter()
来排除那些变量。下面是一段示例代码:
#Change pre/post entries
data[data$UserID == 52118254, "Prepost"][2] <- 2
#Mark rows to delete
data$toDelete <- NA #Makes new empty column for marking deletions
data[data$UserID == 52118284,][2, "toDelete"] <- 1 #Marks row for deletion
#Filter to exclude rows
data %>% filter(is.na(toDelete))
#Optionally add "%>% select(-toDelete)" to remove the extra column
在我的上下文中,这里的优点是一切都是故意的而不是自动的,并且更改锚定到数据而不是可能更改的行号。我仍然欢迎任何反馈或其他实现此目的的方法(也许只需一步)。